Repository: pyccel/pyccel (python)

Issue:
Backtrace due to incompatible types in shapes
### Describe the bug
Backtrace due to incompatible types in shapes. When `set_changeable_shape` is called `_shape` changes type from tuple to list. This causes problems later if the variable is sliced.

### To Reproduce
Provide code to reproduce the behavior:
```python
import numpy as np

if __name__ == '__main__':
    n = 4
    b = True
    if b:
        self_knots = np.zeros(n)
    else:
        self_knots = np.zeros(n+2)
    knots = self_knots[1:-1]
```

### Error details
Provide the generated code, or the error message:
```bash/fortran/c
Traceback (most recent call last):
  File "/home/emily/.local/bin/pyccel", line 8, in <module>
    sys.exit(pyccel())
  File "/home/emily/Code/pyccel/pyccel/commands/console.py", line 266, in pyccel
    execute_pyccel(filename,
  File "/home/emily/Code/pyccel/pyccel/codegen/pipeline.py", line 232, in execute_pyccel
    parser.annotate(verbose = verbose)
  File "/home/emily/Code/pyccel/pyccel/parser/parser.py", line 173, in annotate
    parser = SemanticParser(self._syntax_parser,
  File "/home/emily/Code/pyccel/pyccel/parser/semantic.py", line 261, in __init__
    self.annotate()
  File "/home/emily/Code/pyccel/pyccel/parser/semantic.py", line 318, in annotate
    ast = self._visit(ast)
  File "/home/emily/Code/pyccel/pyccel/parser/semantic.py", line 2279, in _visit
    obj = getattr(self, annotation_method)(expr)
  File "/home/emily/Code/pyccel/pyccel/parser/semantic.py", line 2332, in _visit_Module
    body += self._visit(expr.program.body).body
  File "/home/emily/Code/pyccel/pyccel/parser/semantic.py", line 2279, in _visit
    obj = getattr(self, annotation_method)(expr)
  File "/home/emily/Code/pyccel/pyccel/parser/semantic.py", line 2604, in _visit_CodeBlock
    line = self._visit(b)
  File "/home/emily/Code/pyccel/pyccel/parser/semantic.py", line 2279, in _visit
    obj = getattr(self, annotation_method)(expr)
  File "/home/emily/Code/pyccel/pyccel/parser/semantic.py", line 3381, in _visit_Assign
    rhs = self._visit(rhs)
  File "/home/emily/Code/pyccel/pyccel/parser/semantic.py", line 2279, in _visit
    obj = getattr(self, annotation_method)(expr)
  File "/home/emily/Code/pyccel/pyccel/parser/semantic.py", line 2751, in _visit_IndexedElement
    return self._extract_indexed_from_var(var, args, expr)
  File "/home/emily/Code/pyccel/pyccel/parser/semantic.py", line 892, in _extract_indexed_from_var
    for arg in var[indices].indices:
  File "/home/emily/Code/pyccel/pyccel/ast/variable.py", line 528, in __getitem__
    return IndexedElement(self, *args)
  File "/home/emily/Code/pyccel/pyccel/ast/variable.py", line 760, in __init__
    self._shape = tuple(new_shape) + base.shape[rank:]
TypeError: can only concatenate tuple (not "list") to tuple
```

### Expected behavior
`self._shape` should always be a tuple which fixes the issue.

### Language
Not language specific

### Additional context
Seen in PyGyro


Pull request description:
Fix wrong type of Variable shape
Fix the type of the shape of a Variable following a call to `set_changeable_shape`. Fixes #2094 

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 34098d0d..4a140bac 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -87,6 +87,7 @@ All notable changes to this project will be documented in this file.
 -   #2078 : Fix translation of classes containing comments.
 -   #2041 : Include all type extension methods by default.
 -   #2082 : Allow the use of a list comprehension to initialise an array.
+-   #2094 : Fix slicing of array allocated in an if block.
 
 ### Changed
 
diff --git a/pyccel/ast/variable.py b/pyccel/ast/variable.py
index ade1b1bc..c66947d0 100644
--- a/pyccel/ast/variable.py
+++ b/pyccel/ast/variable.py
@@ -245,7 +245,7 @@ class Variable(TypedAstNode):
         Indicate that the exact shape is unknown, e.g. if the allocate is done in
         an If block.
         """
-        self._shape = [PyccelArrayShapeElement(self, LiteralInteger(i)) for i in range(self.rank)]
+        self._shape = tuple(PyccelArrayShapeElement(self, LiteralInteger(i)) for i in range(self.rank))
 
     def set_init_shape(self, shape):
         """


Test patch:
diff --git a/tests/epyccel/test_arrays_multiple_assignments.py b/tests/epyccel/test_arrays_multiple_assignments.py
index 264b2234..80e2d536 100644
--- a/tests/epyccel/test_arrays_multiple_assignments.py
+++ b/tests/epyccel/test_arrays_multiple_assignments.py
@@ -167,6 +167,26 @@ def test_creation_in_if_heap(language):
     c = np.random.random()
     assert f(c) == g(c)
 
+#==============================================================================
+def test_creation_in_if_heap_shape(language):
+
+    def f(c : 'float'):
+        import numpy as np
+        if c > 0.5:
+            x = np.ones(2, dtype=int)
+        else:
+            x = np.ones(7, dtype=int)
+
+        y = x[1:-1]
+        return y.sum()
+
+    g = epyccel(f, language=language)
+
+    # Check result of pyccelized function
+    import numpy as np
+    c = np.random.random()
+    assert f(c) == g(c)
+
 #==============================================================================
 def test_Reassign_to_Target():