Repository: pyccel/pyccel (language: python)

Issue:
Misleading type names
The current names of the basic underlying types are misleading. These should be changed to make the code easier to understand. The changes should be made as follows:

- `pyccel.ast.basic.Basic` -> `pyccel.ast.basic.PyccelAstNode`
- `pyccel.ast.basic.PyccelAstNode` -> `pyccel.ast.basic.TypedAstNode`
- `pyccel.ast.basic.ScopedNode` -> `pyccel.ast.basic.ScopedAstNode`


Discussion / hints:
Hello Ma'am,
I am willing to work on this but i am completely new to open source,
So can you please let me know exactly how is this to be done.

Hello!
Thank you very much for your interest in Pyccel.
As a new contributor to open source the first thing to do is to fork the repository and make sure that you have your development environment set up properly (see [Getting Started](https://github.com/pyccel/pyccel/blob/devel/developer_docs/getting_started.md) and the [installation docs](https://github.com/pyccel/pyccel/blob/devel/docs/installation.md#from-sources)). If you have any trouble feel free to contact me on our [discord server](https://discord.gg/2Q6hwjfFVb).

Once everything is working you can create a new branch to tackle this issue.
The issue is quite simple as it just involves renaming 3 classes but these classes are used in lots of places in the code. I would recommend using `grep` to find them all and possibly a tool such as `sed` for replacing them. Please make sure you also update any mentions in the documentation folders.

One thing to watch out for, some of our functions are called using type names so they will also need renaming. You can read more about this in the [overview](https://github.com/pyccel/pyccel/blob/devel/developer_docs/overview.md#function-naming-conventionsfile-navigation).

Once you are happy with your changes and the tests seem to be passing, you can go ahead and open a pull request. The review process is described [here](https://github.com/pyccel/pyccel/blob/devel/developer_docs/review_process.md). One thing that might be problematic during the review is the documentation tests. We moved relatively recently to enforce having neat NumPy style docstrings on all our classes and functions. However lots of our old code is still not fully documented. As this issue touches lots of different parts of the code it is likely that it will trigger this test. If there are not many errors then I will probably give you a hand with code suggestions on the review that you can apply with a few clicks. If there are lots, then I may ask @yguclu to make an exception for this PR and temporarily make that test optional.

Hopefully that gives you all the information you need. Are you still willing to work on this? Don't hesitate to contact me or the other devs either here or on the discord if you have any other questions.
Okay ma'am.
I will try to solve this documentation issue.

Fix patch:
diff --git a/AUTHORS b/AUTHORS
index 4997a7313d..f958c32cfe 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -26,3 +26,4 @@ Contributors
 * Anass Maach
 * Othmane Hachim
 * Soukaina Hikma
+* Mudit Loya
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b9c1d46ae7..2051cc8b69 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,6 +3,12 @@ All notable changes to this project will be documented in this file.
 
 ## \[Unreleased\]
 
+### Changed
+
+-   \[INTERNALS\] #1520 : `ScopedNode` -> `ScopedAstNode`.
+-   \[INTERNALS\] #1520 : `PyccelAstNode` -> `TypedAstNode`.
+-   \[INTERNALS\] #1520 : `Basic` -> `PyccelAstNode`.
+
 ### Added
 
 ### Fixed
diff --git a/ci_tools/check_slots.py b/ci_tools/check_slots.py
index a5fc03ae1f..38f543ea50 100644
--- a/ci_tools/check_slots.py
+++ b/ci_tools/check_slots.py
@@ -7,7 +7,7 @@
 import sys
 import json
 from pyccel import ast
-from pyccel.ast.basic import Basic, PyccelAstNode, ScopedNode
+from pyccel.ast.basic import PyccelAstNode, TypedAstNode, ScopedAstNode
 
 def extract_dict_elements(input_dict):
     """
@@ -155,8 +155,8 @@ def fill_dictionary(title, message, file, start_line, end_line, annotation_level
                         error_collection['overridden_slots'].append(fill_dictionary("Overwritten slot values", f"pyccel.ast.{mod_name}.{cls_name}",
                             inspect.getfile(mod), sourceline, sourceline, "failure", f"Slot values are overwritten between `{mod_name}.{cls_name}` and `{c.__name__}`"))
 
-            if Basic in super_classes:
-                if cls_obj not in (PyccelAstNode, ScopedNode) and not isinstance(cls_obj._attribute_nodes, tuple): #pylint: disable=W0212
+            if PyccelAstNode in super_classes:
+                if cls_obj not in (TypedAstNode, ScopedAstNode) and not isinstance(cls_obj._attribute_nodes, tuple): #pylint: disable=W0212
                     sourceline = inspect.getsourcelines(cls_obj)[1]
                     error_collection['missing_attribute_nodes'].append(fill_dictionary("Classes with no `_attribute_nodes`", f"pyccel.ast.{mod_name}.{cls_name}",
                             inspect.getfile(mod), sourceline, sourceline, "failure", f"Missing attribute nodes in : `{mod_name}.{cls_name}`"))
diff --git a/developer_docs/development_conventions.md b/developer_docs/development_conventions.md
index c920c8fe5f..c1c80d0f12 100644
--- a/developer_docs/development_conventions.md
+++ b/developer_docs/development_conventions.md
@@ -72,4 +72,4 @@ class MyClass:
         self.myInstanceVar = 1
 ```
 
-In order to save memory any variables which will remain constant over all instances of a class should be class variables. This discussion usually arises for the properties of the [`PyccelAstNode`](../pyccel/ast/basic.py) and its sub classes. The variables `_dtype`, `_precision`, `_rank`, `_shape`, and `_order` are often seen as instance variables, however for some classes (e.g. [`LiteralInteger`](../pyccel/ast/literals.py)) the values are known and never change. In this case they can be stored as class variables.
+In order to save memory any variables which will remain constant over all instances of a class should be class variables. This discussion usually arises for the properties of the [`TypedAstNode`](../pyccel/ast/basic.py) and its sub classes. The variables `_dtype`, `_precision`, `_rank`, `_shape`, and `_order` are often seen as instance variables, however for some classes (e.g. [`LiteralInteger`](../pyccel/ast/literals.py)) the values are known and never change. In this case they can be stored as class variables.
diff --git a/developer_docs/overview.md b/developer_docs/overview.md
index 41cbc8e539..bd635f4c79 100644
--- a/developer_docs/overview.md
+++ b/developer_docs/overview.md
@@ -26,7 +26,7 @@ The role of this stage has decreased significantly since we moved from [redbaron
 
 This is the most important stage in Pyccel. It is here that all the information about types is calculated. This stage strives to be **language-agnostic**; this means for example, that additional variables required to handle problems appearing in one specific language should not be created here.
 
-When adding functions to this stage the aim is often to create a `PyccelAstNode` (see [ast/basic.py](../pyccel/ast/basic.py)) and correctly define all of its parameters. This information is sometimes readily available (e.g. the type of a `PyccelAdd` can be derived from the type of the variables passed to it), but sometimes the information must be collected from elsewhere (e.g. when creating a `Variable` from a `PyccelSymbol`, which is roughly equivalent to a string). In this case information is needed from a `Scope` instance which is stored in the `scope`.
+When adding functions to this stage the aim is often to create a `TypedAstNode` (see [ast/basic.py](../pyccel/ast/basic.py)) and correctly define all of its parameters. This information is sometimes readily available (e.g. the type of a `PyccelAdd` can be derived from the type of the variables passed to it), but sometimes the information must be collected from elsewhere (e.g. when creating a `Variable` from a `PyccelSymbol`, which is roughly equivalent to a string). In this case information is needed from a `Scope` instance which is stored in the `scope`.
 
 In computer science, the _scope_ is the area of a program where an item (e.g. variable, function, etc.) is recognised. For example a variable defined in a function will not be recognised outside of that function, therefore the function defines its scope.
 
@@ -53,7 +53,7 @@ In the syntactic, semantic, and code generation stages a similar strategy is use
 #### Example
 Suppose we want to generate the code for an object of the class `NumpyTanh`, first we collect the inheritance tree of `NumpyTanh`. This gives us:
 ```python
-('NumpyTanh', 'NumpyUfuncUnary', 'NumpyUfuncBase', 'PyccelInternalFunction', 'PyccelAstNode', 'Basic')
+('NumpyTanh', 'NumpyUfuncUnary', 'NumpyUfuncBase', 'PyccelInternalFunction', 'TypedAstNode', 'PyccelAstNode')
 ```
 Therefore the print functions which are acceptable for visiting this object are:
 
@@ -61,8 +61,8 @@ Therefore the print functions which are acceptable for visiting this object are:
 -   `_print_NumpyUfuncUnary` 
 -   `_print_NumpyUfuncBase` 
 -   `_print_PyccelInternalFunction` 
+-   `_print_TypedAstNode` 
 -   `_print_PyccelAstNode` 
--   `_print_Basic` 
 
 We run through these possible functions choosing the one which is the most specialised. If none of these methods exist, then an error is raised.
 
@@ -70,7 +70,7 @@ In the case of `NumpyTanh` the function which will be selected is `_print_NumpyU
 
 ### AST
 
-The objects as understood by Pyccel are each described by classes which inherit from [pyccel.ast.basic.Basic](../pyccel/ast/basic.py).
+The objects as understood by Pyccel are each described by classes which inherit from [pyccel.ast.basic.PyccelAstNode](../pyccel/ast/basic.py).
 These classes are found in the [ast](../pyccel/ast) folder.
 The objects in the Abstract Syntax Tree (AST) are described in several files.
 There is one file for each supported extension module and files to group concepts, e.g. literals/operators/built-in functions.
diff --git a/developer_docs/scope.md b/developer_docs/scope.md
index 134dc1bbdd..7f8f44fee0 100644
--- a/developer_docs/scope.md
+++ b/developer_docs/scope.md
@@ -6,9 +6,9 @@ In Pyccel, a `Scope` is an object defined in [parser/scope.py](../pyccel/parser/
 
 Each of these objects must be inserted into the scope using and insert function.
 
-## `ScopedNode`
+## `ScopedAstNode`
 
-Each scope is associated with a class, e.g. `FunctionDef`, `For`, `Module`. These classes inherit from the `ScopedNode` class. The scope associated with the class instance, is saved within the class. This makes the scope available when the class instance is available. This is important so as to correctly set the `scope` variable in the `SemanticParser` and the different `CodePrinter`s.
+Each scope is associated with a class, e.g. `FunctionDef`, `For`, `Module`. These classes inherit from the `ScopedAstNode` class. The scope associated with the class instance, is saved within the class. This makes the scope available when the class instance is available. This is important so as to correctly set the `scope` variable in the `SemanticParser` and the different `CodePrinter`s.
 
 ## Name collisions
 
diff --git a/developer_docs/semantic_stage.md b/developer_docs/semantic_stage.md
index 43f9fc4e84..ad0e06ff40 100644
--- a/developer_docs/semantic_stage.md
+++ b/developer_docs/semantic_stage.md
@@ -31,7 +31,7 @@ Each of these `_visit_X` functions should internally call the `_visit` function
 
 Variables and objects which can be saved in variables (e.g. literals and arrays), are  characterised by their type.
 The type indicates all the information that allows the object to be declared in a low-level language.
-The interface to access these characteristics is defined in the super class [`pyccel.ast.basic.PyccelAstNode`](../pyccel/ast/basic.py).
+The interface to access these characteristics is defined in the super class [`pyccel.ast.basic.TypedAstNode`](../pyccel/ast/basic.py).
 The characteristics are:
 -   **data type** : boolean/integer/float/complex/class type/etc
 -   **precision** : The number of bytes required to store an object of this data type
@@ -42,7 +42,7 @@ The characteristics are:
 The type of the different objects is determined in 2 different places.
 
 `Variable` objects are created in the `SemanticParser._visit_Assign` function.
-Their type is determined from the type of the right hand side, which should be a `PyccelAstNode`.
+Their type is determined from the type of the right hand side, which should be a `TypedAstNode`.
 The function `SemanticParser._infer_type` infers the type from the right hand side object and returns a dictionary describing the different characteristics.
 This dictionary is passed to the function `SemanticParser._assign_lhs_variable` which should always be used to create variables as it runs various checks including the validity of the type (e.g checking if the datatype has changed).
 In addition to the above characteristics `Variable` objects also have a few additional characteristics such as the `memory_location` which are also determined in the `SemanticParser._infer_type` function.
@@ -155,12 +155,12 @@ Variable declarations are created in the printer when needed from the scope vari
 
 ## Object Tree
 
-All the objects in the Pyccel AST inherit from [`pyccel.ast.basic.Basic`](../pyccel/ast/basic.py).
+All the objects in the Pyccel AST inherit from [`pyccel.ast.basic.PyccelAstNode`](../pyccel/ast/basic.py).
 This super-class stores information about how the various objects are related.
 This allows the class to provide functions such as `get_user_nodes` (which returns all objects of a given type which use the node), `get_attribute_nodes` (which returns all objects of a given type which are used by the node), `is_attribute_of` (which indicates if the node is used by the argument), `is_user_of` (which indicates if the node uses the argument), and `substitute` (which allows all occurrences of an object in the node to be replaced by a different object).
-See [`pyccel.ast.basic.Basic`](../pyccel/ast/basic.py) for more information about these functions and other useful utility functions.
+See [`pyccel.ast.basic.PyccelAstNode`](../pyccel/ast/basic.py) for more information about these functions and other useful utility functions.
 
-The tree is constructed in `Basic.__init__` using the `_attribute_nodes` attribute to recognise the names of attributes which must be added to the tree.
+The tree is constructed in `PyccelAstNode.__init__` using the `_attribute_nodes` attribute to recognise the names of attributes which must be added to the tree.
 Nevertheless the object tree should be considered in two situations.
 
 Firstly, if the object is constructed and AST objects are then added to it (e.g. the member function `pyccel.ast.core.CodeBlock.insert2body` used for the garbage collector).
@@ -176,7 +176,7 @@ However if this were done there would be multiple user nodes from both the seman
 For example, if we need to have access to the containing function we could do `expr.get_user_nodes(FunctionDef)`.
 We expect that this only returns semantic objects if `expr` is a result of the semantic stage.
 However if objects such as `pyccel.ast.core.Continue` are returned as is, then we would get access to both the syntactic and the semantic versions of the containing function without any way to distinguish between the two.
-To avoid this it is important to call the `pyccel.ast.basic.Basic.clear_user_nodes` function to remove the syntactic objects from the tree before returning the object:
+To avoid this it is important to call the `pyccel.ast.basic.PyccelAstNode.clear_user_nodes` function to remove the syntactic objects from the tree before returning the object:
 ```python
 def _visit_Continue(self, expr):
     expr.clear_user_nodes()
diff --git a/developer_docs/syntactic_stage.md b/developer_docs/syntactic_stage.md
index 29a133cbef..9a85b36081 100644
--- a/developer_docs/syntactic_stage.md
+++ b/developer_docs/syntactic_stage.md
@@ -25,7 +25,7 @@ def _visit_ClassName(self, stmt):
     ...
     return Y
 ```
-where `Y` must be an object of a class which inherits from [`pyccel.ast.basic.Basic`](../pyccel/ast/basic.py).
+where `Y` must be an object of a class which inherits from [`pyccel.ast.basic.PyccelAstNode`](../pyccel/ast/basic.py).
 Each of these `_visit_X` functions should internally call the `_visit` function on each of the elements of the object to obtain Pyccel AST nodes which can be combined to create a Pyccel AST node representing the current object.
 
 ### Example
@@ -76,7 +76,7 @@ The most important arguments are:
     -   _fatal_ : An error will be printed and Pyccel will stop executing. This level should rarely be needed in the syntactic stage as a failure in one visitation function (`_visit_X`) should not affect the execution of another. It is preferable to show the users all errors at once
 
 Although the failures in visitation functions (`_visit_X`) do not affect other visitation functions it is still important to ensure that the functions provide a valid output.
-In the `SyntacticParser` all `_visit_X` should return a Pyccel AST object (an object which inherits from [`pyccel.ast.basic.Basic`](../pyccel/ast/basic.py), `pyccel.ast.core.EmptyNode` can be used to ensure this restriction is fulfilled.
+In the `SyntacticParser` all `_visit_X` should return a Pyccel AST object (an object which inherits from [`pyccel.ast.basic.PyccelAstNode`](../pyccel/ast/basic.py), `pyccel.ast.core.EmptyNode` can be used to ensure this restriction is fulfilled.
 This is important to avoid errors caused by the construction of the tree which relates the objects (for more details see the [semantic stage](semantic_stage.md#Object-tree)).
 
 ## Headers
@@ -119,7 +119,7 @@ body = self._visit(stmt.body)
 
 ### Scoped Node
 
-Any functions visiting a class which inherits from `ScopedNode` must create a new scope before visiting objects and exit it after everything inside the scope has been visited.
+Any functions visiting a class which inherits from `ScopedAstNode` must create a new scope before visiting objects and exit it after everything inside the scope has been visited.
 The scope must then be passed to the class using the keyword argument `scope`.
 Care should be taken here as this keyword is not compulsory[^1].
 
diff --git a/pyccel/ast/basic.py b/pyccel/ast/basic.py
index 965f4950f4..4d2fc1a22e 100644
--- a/pyccel/ast/basic.py
+++ b/pyccel/ast/basic.py
@@ -4,16 +4,16 @@
 #------------------------------------------------------------------------------------------#
 
 """
-This module contains classes from which all pyccel nodes inherit.
-They are:
-- Basic, which provides a python AST
-- PyccelAstNode which describes each PyccelAstNode
+This module contains classes from which all pyccel nodes inherit. They are:
+- PyccelAstNode, which provides a base class for our Python AST nodes;
+- TypedAstNode, which inherits from PyccelAstNode and provides a base class for
+  AST nodes requiring type descriptors.
 """
 import ast
 
 from pyccel.utilities.stage   import PyccelStage
 
-__all__ = ('Basic', 'Immutable', 'PyccelAstNode', 'ScopedNode')
+__all__ = ('PyccelAstNode', 'Immutable', 'TypedAstNode', 'ScopedAstNode')
 
 dict_keys   = type({}.keys())
 dict_values = type({}.values())
@@ -25,13 +25,13 @@
 #==============================================================================
 class Immutable:
     """ Superclass for classes which cannot inherit
-    from Basic """
+    from PyccelAstNode """
     __slots__ = ()
 
 #==============================================================================
-class Basic:
+class PyccelAstNode:
     """
-    Basic class from which all objects in the Pyccel AST inherit.
+    PyccelAstNode class from which all objects in the Pyccel AST inherit.
 
     This foundational class provides all the functionalities that are common to
     objects in the Pyccel AST. This includes the construction and navigation of
@@ -52,7 +52,7 @@ def __init__(self):
 
             from pyccel.ast.literals import convert_to_literal
 
-            if Basic._ignore(c):
+            if PyccelAstNode._ignore(c):
                 continue
 
             elif isinstance(c, (int, float, complex, str, bool)):
@@ -63,19 +63,19 @@ def __init__(self):
             elif iterable(c):
                 size = len(c)
                 c = tuple(ci if (not isinstance(ci, (int, float, complex, str, bool)) \
-                                 or Basic._ignore(ci)) \
+                                 or PyccelAstNode._ignore(ci)) \
                         else convert_to_literal(ci) for ci in c if not iterable(ci))
                 if len(c) != size:
-                    raise TypeError("Basic child cannot be a tuple of tuples")
+                    raise TypeError("PyccelAstNode child cannot be a tuple of tuples")
                 setattr(self, c_name, c)
 
-            elif not isinstance(c, Basic):
-                raise TypeError("Basic child must be a Basic or a tuple not {}".format(type(c)))
+            elif not isinstance(c, PyccelAstNode):
+                raise TypeError("PyccelAstNode child must be a PyccelAstNode or a tuple not {}".format(type(c)))
 
 
             if isinstance(c, tuple):
                 for ci in c:
-                    if not Basic._ignore(ci):
+                    if not PyccelAstNode._ignore(ci):
                         ci.set_current_user_node(self)
             else:
                 c.set_current_user_node(self)
@@ -184,7 +184,7 @@ def is_attribute_of(self, node):
 
         Parameters
         ----------
-        node : Basic
+        node : PyccelAstNode
                The object whose attributes we are interested in
 
         Results
@@ -199,7 +199,7 @@ def is_user_of(self, node, excluded_nodes = ()):
 
         Parameters
         ----------
-        node           : Basic
+        node           : PyccelAstNode
                       The object whose users we are interested in
         excluded_nodes : tuple of types
                       Types for which is_user_of should not be called
@@ -326,11 +326,25 @@ def set_fst(self, fst):
 
     @property
     def fst(self):
+        """
+        Get the AST object which Python parsed in the original code.
+
+        Get the AST (abstract syntax tree) object which Python parsed
+        in the original code. This object describes the Python code being
+        translated. It provides line numbers and columns which can be
+        used to report the origin of any potential errors.
+
+        Returns
+        -------
+        ast.AST
+            The AST object which was parsed.
+        """
         if len(self._fst) == 1:
             return self._fst[0]
         else:
             return None
 
+
     def toggle_recursion(self):
         """ Change the recursion state
         """
@@ -344,7 +358,7 @@ def recursion_in_progress(self):
 
     def get_all_user_nodes(self):
         """ Returns all the objects user nodes.
-        This function should only be called in Basic
+        This function should only be called in PyccelAstNode
         """
         return self._user_nodes
 
@@ -391,7 +405,7 @@ def remove_user_node(self, user_node, invalidate = True):
 
         Parameters
         ----------
-        user_node : Basic
+        user_node : PyccelAstNode
                     Node which previously used the current node
         invalidate : bool
                     Indicates whether the removed object should
@@ -435,7 +449,7 @@ def update_pyccel_staging(self):
         """
         self._pyccel_staging = pyccel_stage.current_stage
 
-class PyccelAstNode(Basic):
+class TypedAstNode(PyccelAstNode):
     """Class from which all nodes containing objects inherit
     """
     __slots__  = ()
@@ -470,6 +484,18 @@ def order(self):
         return self._order # pylint: disable=no-member
 
     def copy_attributes(self, x):
+        """
+        Copy the attributes describing a TypedAstNode into this node.
+
+        Copy the attributes which describe the TypedAstNode passed as
+        argument (dtype, precision, shape, rank, order) into this node
+        so that the two nodes can be stored in the same object.
+
+        Parameters
+        ----------
+        x : TypedAstNode
+            The node from which the attributes should be copied.
+        """
         self._shape     = x.shape
         self._rank      = x.rank
         self._dtype     = x.dtype
@@ -478,7 +504,7 @@ def copy_attributes(self, x):
 
 
 #------------------------------------------------------------------------------
-class ScopedNode(Basic):
+class ScopedAstNode(PyccelAstNode):
     """ Class from which all objects with a scope inherit
     """
     __slots__ = ('_scope',)
diff --git a/pyccel/ast/bind_c.py b/pyccel/ast/bind_c.py
index b33f82fab4..d69717ead8 100644
--- a/pyccel/ast/bind_c.py
+++ b/pyccel/ast/bind_c.py
@@ -8,7 +8,7 @@
 file.
 """
 
-from pyccel.ast.basic import Basic
+from pyccel.ast.basic import PyccelAstNode
 from pyccel.ast.core import Module
 from pyccel.ast.core import FunctionDef
 from pyccel.ast.core import FunctionDefArgument, FunctionDefResult
@@ -543,7 +543,7 @@ def wrapper_function(self):
 #                                   Utility functions
 # =======================================================================================
 
-class CLocFunc(Basic):
+class CLocFunc(PyccelAstNode):
     """
     Creates a C-compatible pointer to the argument.
 
@@ -588,7 +588,7 @@ def result(self):
 
 # =======================================================================================
 
-class C_F_Pointer(Basic):
+class C_F_Pointer(PyccelAstNode):
     """
     Creates a Fortran array pointer from a C pointer and size information.
 
diff --git a/pyccel/ast/bitwise_operators.py b/pyccel/ast/bitwise_operators.py
index fc59dc6d73..6914f9a64f 100644
--- a/pyccel/ast/bitwise_operators.py
+++ b/pyccel/ast/bitwise_operators.py
@@ -37,7 +37,7 @@ class PyccelInvert(PyccelUnaryOperator):
 
     Parameters
     ----------
-    arg: PyccelAstNode
+    arg: TypedAstNode
         The argument passed to the operator
     """
     __slots__ = ()
@@ -64,9 +64,9 @@ class PyccelBitOperator(PyccelOperator):
 
     Parameters
     ----------
-    arg1: PyccelAstNode
+    arg1: TypedAstNode
         The first argument passed to the operator
-    arg2: PyccelAstNode
+    arg2: TypedAstNode
         The second argument passed to the operator
     """
     _shape = None
@@ -126,9 +126,9 @@ class PyccelRShift(PyccelBitOperator):
 
     Parameters
     ----------
-    arg1: PyccelAstNode
+    arg1: TypedAstNode
         The first argument passed to the operator
-    arg2: PyccelAstNode
+    arg2: TypedAstNode
         The second argument passed to the operator
     """
     __slots__ = ()
@@ -149,9 +149,9 @@ class PyccelLShift(PyccelBitOperator):
 
     Parameters
     ----------
-    arg1: PyccelAstNode
+    arg1: TypedAstNode
         The first argument passed to the operator
-    arg2: PyccelAstNode
+    arg2: TypedAstNode
         The second argument passed to the operator
     """
     __slots__ = ()
@@ -168,9 +168,9 @@ class PyccelBitComparisonOperator(PyccelBitOperator):
 
     Parameters
     ----------
-    arg1: PyccelAstNode
+    arg1: TypedAstNode
         The first argument passed to the operator
-    arg2: PyccelAstNode
+    arg2: TypedAstNode
         The second argument passed to the operator
     """
     __slots__ = ()
@@ -197,9 +197,9 @@ class PyccelBitXor(PyccelBitComparisonOperator):
 
     Parameters
     ----------
-    arg1: PyccelAstNode
+    arg1: TypedAstNode
         The first argument passed to the operator
-    arg2: PyccelAstNode
+    arg2: TypedAstNode
         The second argument passed to the operator
     """
     __slots__ = ()
@@ -220,9 +220,9 @@ class PyccelBitOr(PyccelBitComparisonOperator):
 
     Parameters
     ----------
-    arg1: PyccelAstNode
+    arg1: TypedAstNode
         The first argument passed to the operator
-    arg2: PyccelAstNode
+    arg2: TypedAstNode
         The second argument passed to the operator
     """
     __slots__ = ()
@@ -243,9 +243,9 @@ class PyccelBitAnd(PyccelBitComparisonOperator):
 
     Parameters
     ----------
-    arg1: PyccelAstNode
+    arg1: TypedAstNode
         The first argument passed to the operator
-    arg2: PyccelAstNode
+    arg2: TypedAstNode
         The second argument passed to the operator
     """
     __slots__ = ()
diff --git a/pyccel/ast/builtins.py b/pyccel/ast/builtins.py
index 74de8a6129..debfb55dcb 100644
--- a/pyccel/ast/builtins.py
+++ b/pyccel/ast/builtins.py
@@ -14,7 +14,7 @@
 
 from pyccel.utilities.stage import PyccelStage
 
-from .basic     import Basic, PyccelAstNode
+from .basic     import PyccelAstNode, TypedAstNode
 from .datatypes import (NativeInteger, NativeBool, NativeFloat,
                         NativeComplex, NativeString, str_dtype,
                         NativeGeneric)
@@ -141,7 +141,7 @@ class PythonConjugate(PyccelInternalFunction):
 
     Parameters
     ----------
-    arg : PyccelAstNode
+    arg : TypedAstNode
         The variable/expression which was passed to the
         conjugate function.
     """
@@ -173,7 +173,7 @@ def __str__(self):
         return 'Conjugate({0})'.format(str(self.internal_var))
 
 #==============================================================================
-class PythonBool(PyccelAstNode):
+class PythonBool(TypedAstNode):
     """ Represents a call to Python's native bool() function.
     """
     __slots__ = ('_arg',)
@@ -205,7 +205,7 @@ def __str__(self):
         return 'Bool({})'.format(str(self.arg))
 
 #==============================================================================
-class PythonComplex(PyccelAstNode):
+class PythonComplex(TypedAstNode):
     """ Represents a call to Python's native complex() function.
     """
     __slots__ = ('_real_part', '_imag_part', '_internal_var', '_is_cast')
@@ -307,7 +307,7 @@ def __str__(self):
         return "complex({}, {})".format(str(self.real), str(self.imag))
 
 #==============================================================================
-class PythonEnumerate(Basic):
+class PythonEnumerate(PyccelAstNode):
 
     """
     Represents the enumerate stmt
@@ -319,7 +319,7 @@ class PythonEnumerate(Basic):
 
     def __init__(self, arg, start = None):
         if pyccel_stage != "syntactic" and \
-                not isinstance(arg, PyccelAstNode):
+                not isinstance(arg, TypedAstNode):
             raise TypeError('Expecting an arg of valid type')
         self._element = arg
         self._start   = start or LiteralInteger(0)
@@ -346,7 +346,7 @@ def length(self):
         return PythonLen(self.element)
 
 #==============================================================================
-class PythonFloat(PyccelAstNode):
+class PythonFloat(TypedAstNode):
     """ Represents a call to Python's native float() function.
     """
     __slots__ = ('_arg')
@@ -377,7 +377,7 @@ def __str__(self):
         return 'float({0})'.format(str(self.arg))
 
 #==============================================================================
-class PythonInt(PyccelAstNode):
+class PythonInt(TypedAstNode):
     """ Represents a call to Python's native int() function.
     """
 
@@ -405,7 +405,7 @@ def arg(self):
         return self._arg
 
 #==============================================================================
-class PythonTuple(PyccelAstNode):
+class PythonTuple(TypedAstNode):
     """
     Class representing a call to Python's native tuple() function.
 
@@ -415,7 +415,7 @@ class PythonTuple(PyccelAstNode):
 
     Parameters
     ----------
-    *args : tuple of PyccelAstNode
+    *args : tuple of TypedAstNode
         The arguments passed to the tuple function.
     """
     __slots__ = ('_args','_inconsistent_shape','_is_homogeneous',
@@ -583,7 +583,7 @@ class PythonList(PythonTuple):
     __slots__ = ()
 
 #==============================================================================
-class PythonMap(Basic):
+class PythonMap(PyccelAstNode):
     """ Represents the map stmt
     """
     __slots__ = ('_func','_func_args')
@@ -617,11 +617,11 @@ def length(self):
         return PythonLen(self.func_args)
 
 #==============================================================================
-class PythonPrint(Basic):
+class PythonPrint(PyccelAstNode):
 
     """Represents a print function in the code.
 
-    expr : PyccelAstNode
+    expr : TypedAstNode
         The expression to print
     file: String (Optional)
         Select 'stdout' (default) or 'stderr' to print to
@@ -655,7 +655,7 @@ def file(self):
         return self._file
 
 #==============================================================================
-class PythonRange(Basic):
+class PythonRange(PyccelAstNode):
 
     """
     Represents a range.
@@ -779,7 +779,7 @@ class PythonSum(PyccelInternalFunction):
     _order = None
 
     def __init__(self, arg):
-        if not isinstance(arg, PyccelAstNode):
+        if not isinstance(arg, TypedAstNode):
             raise TypeError('Unknown type of  %s.' % type(arg))
         self._dtype = arg.dtype
         self._precision = -1
@@ -846,14 +846,14 @@ def __init__(self, *x):
         super().__init__(x)
 
 #==============================================================================
-class Lambda(Basic):
+class Lambda(PyccelAstNode):
     """Represents a call to python lambda for temporary functions
 
     Parameters
     ==========
     variables : tuple of symbols
                 The arguments to the lambda expression
-    expr      : PyccelAstNode
+    expr      : TypedAstNode
                 The expression carried out when the lambda function is called
     """
     __slots__ = ('_variables', '_expr')
@@ -889,7 +889,7 @@ def __str__(self):
                 expr = self.expr)
 
 #==============================================================================
-class PythonType(Basic):
+class PythonType(PyccelAstNode):
     """
     Represents a call to the Python builtin `type` function.
 
@@ -902,14 +902,14 @@ class PythonType(Basic):
 
     Parameters
     ==========
-    obj : PyccelAstNode
+    obj : TypedAstNode
           The object whose type we wish to investigate.
     """
     __slots__ = ('_dtype','_precision','_obj')
     _attribute_nodes = ('_obj',)
 
     def __init__(self, obj):
-        if not isinstance (obj, PyccelAstNode):
+        if not isinstance (obj, TypedAstNode):
             raise PyccelError("Python's type function is not implemented for {} object".format(type(obj)))
         self._dtype = obj.dtype
         self._precision = obj.precision
diff --git a/pyccel/ast/c_concepts.py b/pyccel/ast/c_concepts.py
index 0e5f807f42..c02586956a 100644
--- a/pyccel/ast/c_concepts.py
+++ b/pyccel/ast/c_concepts.py
@@ -7,14 +7,14 @@
 Module representing object address.
 """
 
-from .basic import PyccelAstNode, Basic
+from .basic import TypedAstNode, PyccelAstNode
 from .literals  import LiteralString
 
 __all__ = ('CMacro',
            'CStringExpression',
            'ObjectAddress')
 
-class ObjectAddress(PyccelAstNode):
+class ObjectAddress(TypedAstNode):
     """Represents the address of an object.
     ObjectAddress(Variable('int','a'))                            is  &a
     ObjectAddress(Variable('int','a', memory_handling='alias'))   is   a
@@ -24,8 +24,8 @@ class ObjectAddress(PyccelAstNode):
     _attribute_nodes = ('_obj',)
 
     def __init__(self, obj):
-        if not isinstance(obj, PyccelAstNode):
-            raise TypeError("object must be an instance of PyccelAstNode")
+        if not isinstance(obj, TypedAstNode):
+            raise TypeError("object must be an instance of TypedAstNode")
         self._obj       = obj
         self._rank      = obj.rank
         self._shape     = obj.shape
@@ -41,7 +41,7 @@ def obj(self):
         return self._obj
 
 #------------------------------------------------------------------------------
-class CStringExpression(Basic):
+class CStringExpression(PyccelAstNode):
     """
     Internal class used to hold a C string that has LiteralStrings and C macros.
 
@@ -182,7 +182,7 @@ def expression(self):
         return self._expression
 
 #------------------------------------------------------------------------------
-class CMacro(Basic):
+class CMacro(PyccelAstNode):
     """Represents a c macro"""
     __slots__ = ('_macro',)
     _attribute_nodes  = ()
diff --git a/pyccel/ast/cmathext.py b/pyccel/ast/cmathext.py
index 42d934ffda..884eeddc55 100644
--- a/pyccel/ast/cmathext.py
+++ b/pyccel/ast/cmathext.py
@@ -54,7 +54,7 @@ class CmathFunctionBool(MathFunctionBase):
 
     Paramters
     ---------
-    z : PyccelAstNode
+    z : TypedAstNode
         The expression passed as argument to the function.
     """
     __slots__ = ()
@@ -70,7 +70,7 @@ class CmathFunctionComplex(MathFunctionBase):
 
     Paramters
     ---------
-    z : PyccelAstNode
+    z : TypedAstNode
         The expression passed as argument to the function.
     """
     __slots__ = ()
@@ -80,7 +80,7 @@ class CmathFunctionComplex(MathFunctionBase):
     _rank  = 0
     _order = None
 
-    def __init__(self, z : 'PyccelAstNode'):
+    def __init__(self, z : 'TypedAstNode'):
         super().__init__(z)
 
 #==============================================================================
@@ -99,7 +99,7 @@ class CmathAcos    (CmathFunctionComplex):
 
     Parameters
     ----------
-    z : PyccelAstNode
+    z : TypedAstNode
         The expression passed as argument to the function.
     """
     __slots__ = ()
@@ -115,7 +115,7 @@ class CmathAcosh   (CmathFunctionComplex):
 
     Parameters
     ----------
-    z : PyccelAstNode
+    z : TypedAstNode
         The expression passed as argument to the function.
     """
     __slots__ = ()
@@ -131,7 +131,7 @@ class CmathAsin    (CmathFunctionComplex):
 
     Parameters
     ----------
-    z : PyccelAstNode
+    z : TypedAstNode
         The expression passed as argument to the function.
     """
     __slots__ = ()
@@ -147,7 +147,7 @@ class CmathAsinh   (CmathFunctionComplex):
 
     Parameters
     ----------
-    z : PyccelAstNode
+    z : TypedAstNode
         The expression passed as argument to the function.
     """
     __slots__ = ()
@@ -163,7 +163,7 @@ class CmathAtan    (CmathFunctionComplex):
 
     Parameters
     ----------
-    z : PyccelAstNode
+    z : TypedAstNode
         The expression passed as argument to the function.
     """
     __slots__ = ()
@@ -179,7 +179,7 @@ class CmathAtanh    (CmathFunctionComplex):
 
     Parameters
     ----------
-    z : PyccelAstNode
+    z : TypedAstNode
         The expression passed as argument to the function.
     """
     __slots__ = ()
@@ -195,7 +195,7 @@ class CmathCos     (CmathFunctionComplex):
 
     Parameters
     ----------
-    z : PyccelAstNode
+    z : TypedAstNode
         The expression passed as argument to the function.
     """
     __slots__ = ()
@@ -211,7 +211,7 @@ class CmathCosh    (CmathFunctionComplex):
 
     Parameters
     ----------
-    z : PyccelAstNode
+    z : TypedAstNode
         The expression passed as argument to the function.
     """
     __slots__ = ()
@@ -227,7 +227,7 @@ class CmathExp     (CmathFunctionComplex):
 
     Parameters
     ----------
-    z : PyccelAstNode
+    z : TypedAstNode
         The expression passed as argument to the function.
     """
     __slots__ = ()
@@ -243,7 +243,7 @@ class CmathSin     (CmathFunctionComplex):
 
     Parameters
     ----------
-    z : PyccelAstNode
+    z : TypedAstNode
         The expression passed as argument to the function.
     """
     __slots__ = ()
@@ -259,7 +259,7 @@ class CmathSinh    (CmathFunctionComplex):
 
     Parameters
     ----------
-    z : PyccelAstNode
+    z : TypedAstNode
         The expression passed as argument to the function.
     """
     __slots__ = ()
@@ -275,7 +275,7 @@ class CmathSqrt    (CmathFunctionComplex):
 
     Parameters
     ----------
-    z : PyccelAstNode
+    z : TypedAstNode
         The expression passed as argument to the function.
     """
     __slots__ = ()
@@ -291,7 +291,7 @@ class CmathTan     (CmathFunctionComplex):
 
     Parameters
     ----------
-    z : PyccelAstNode
+    z : TypedAstNode
         The expression passed as argument to the function.
     """
     __slots__ = ()
@@ -307,7 +307,7 @@ class CmathTanh    (CmathFunctionComplex):
 
     Parameters
     ----------
-    z : PyccelAstNode
+    z : TypedAstNode
         The expression passed as argument to the function.
     """
     __slots__ = ()
@@ -325,7 +325,7 @@ class CmathIsclose (CmathFunctionBool):
 
     Parameters
     ----------
-    z : PyccelAstNode
+    z : TypedAstNode
         The expression passed as argument to the function.
     """
     __slots__ = ()
@@ -341,7 +341,7 @@ class CmathIsfinite(CmathFunctionBool):
 
     Parameters
     ----------
-    z : PyccelAstNode
+    z : TypedAstNode
         The expression passed as argument to the function.
     """
     __slots__ = ()
@@ -362,7 +362,7 @@ class CmathIsinf   (CmathFunctionBool):
 
     Parameters
     ----------
-    z : PyccelAstNode
+    z : TypedAstNode
         The expression passed as argument to the function.
     """
     __slots__ = ()
@@ -383,7 +383,7 @@ class CmathIsnan   (CmathFunctionBool):
 
     Parameters
     ----------
-    z : PyccelAstNode
+    z : TypedAstNode
         The expression passed as argument to the function.
     """
     __slots__ = ()
@@ -407,7 +407,7 @@ class CmathPhase(PyccelInternalFunction):
 
     Parameters
     ----------
-    z : PyccelAstNode
+    z : TypedAstNode
         The expression passed as argument to the function.
     """
     __slots__ = ()
@@ -423,7 +423,7 @@ class CmathPolar(PyccelInternalFunction):
 
     Parameters
     ----------
-    z : PyccelAstNode
+    z : TypedAstNode
         The expression passed as argument to the function.
     """
     __slots__ = ()
@@ -445,9 +445,9 @@ class CmathRect(PyccelInternalFunction):
 
     Parameters
     ----------
-    r : PyccelAstNode
+    r : TypedAstNode
         The first argument to the function, representing the radius.
-    phi : PyccelAstNode
+    phi : TypedAstNode
         The second argument to the function, representing the polar angle.
     """
     __slots__ = ()
diff --git a/pyccel/ast/core.py b/pyccel/ast/core.py
index 089b6fee25..7cf0b0bcdd 100644
--- a/pyccel/ast/core.py
+++ b/pyccel/ast/core.py
@@ -15,7 +15,7 @@
 from pyccel.utilities.stage   import PyccelStage
 from pyccel.utilities.strings import create_incremented_string
 
-from .basic     import Basic, PyccelAstNode, iterable, ScopedNode
+from .basic     import PyccelAstNode, TypedAstNode, iterable, ScopedAstNode
 from .builtins  import (PythonEnumerate, PythonLen, PythonMap, PythonTuple,
                         PythonRange, PythonZip, PythonBool, Lambda)
 from .datatypes import (datatype, DataType, NativeSymbol,
@@ -161,7 +161,7 @@ def subs(expr, new_elements):
         new_expr = expr.subs(new_elements)
         new_expr.set_fst(expr.fst)
         return new_expr
-    elif isinstance(expr, PyccelAstNode):
+    elif isinstance(expr, TypedAstNode):
         return expr.subs(new_elements)
 
     else:
@@ -205,7 +205,7 @@ def create_variable(forbidden_names, prefix = None, counter = 1):
     return PyccelSymbol(name, is_temp=True), counter
 
 
-class AsName(Basic):
+class AsName(PyccelAstNode):
 
     """
     Represents a renaming of a variable, used with Import.
@@ -222,7 +222,7 @@ class AsName(Basic):
 
     Parameters
     ==========
-    obj    : Basic or BasicType
+    obj    : PyccelAstNode or PyccelAstNodeType
              The variable, function, or module being renamed
     target : str
              name of variable or function in this context
@@ -232,9 +232,9 @@ class AsName(Basic):
 
     def __init__(self, obj, target):
         if pyccel_stage != "syntactic":
-            assert (isinstance(obj, Basic) and \
+            assert (isinstance(obj, PyccelAstNode) and \
                     not isinstance(obj, PyccelSymbol)) or \
-                   (isinstance(obj, type) and issubclass(obj, Basic))
+                   (isinstance(obj, type) and issubclass(obj, PyccelAstNode))
         self._obj = obj
         self._target = target
         super().__init__()
@@ -282,13 +282,13 @@ def __hash__(self):
         return hash(self.target)
 
 
-class Duplicate(PyccelAstNode):
+class Duplicate(TypedAstNode):
 
     """ this is equivalent to the * operator for python tuples.
 
     Parameters
     ----------
-    value : PyccelAstNode
+    value : TypedAstNode
            an expression which represents the initilized value of the list
 
     shape : the shape of the array
@@ -321,13 +321,13 @@ def __str__(self):
     def __repr__(self):
         return '{} * {}'.format(repr(self.val), repr(self.length))
 
-class Concatenate(PyccelAstNode):
+class Concatenate(TypedAstNode):
 
     """ this is equivalent to the + operator for python tuples
 
     Parameters
     ----------
-    args : PyccelAstNodes
+    args : TypedAstNodes
            The tuples
     """
     __slots__ = ('_args','_dtype','_precision','_rank','_shape','_order')
@@ -349,13 +349,13 @@ def args(self):
         return self._args
 
 
-class Assign(Basic):
+class Assign(PyccelAstNode):
 
     """Represents variable assignment for code generation.
 
     Parameters
     ----------
-    lhs : PyccelAstNode
+    lhs : TypedAstNode
         In the syntactic stage:
            Object representing the lhs of the expression. These should be
            singular objects, such as one would use in writing code. Notable types
@@ -364,11 +364,11 @@ class Assign(Basic):
         In the semantic stage:
            Variable or IndexedElement
 
-    rhs : PyccelAstNode
+    rhs : TypedAstNode
         In the syntactic stage:
           Object representing the rhs of the expression
         In the semantic stage :
-          PyccelAstNode with the same shape as the lhs
+          TypedAstNode with the same shape as the lhs
 
     status: None, str
         if lhs is not allocatable, then status is None.
@@ -480,7 +480,7 @@ def is_symbolic_alias(self):
         return False
 
 #------------------------------------------------------------------------------
-class Allocate(Basic):
+class Allocate(PyccelAstNode):
     """
     Represents memory allocation for code generation.
 
@@ -577,7 +577,7 @@ def __hash__(self):
         return hash((id(self.variable), self.shape, self.order, self.status))
 
 #------------------------------------------------------------------------------
-class Deallocate(Basic):
+class Deallocate(PyccelAstNode):
     """
     Represents memory deallocation (usually of an array) for code generation.
     This is relevant to low-level target languages, such as C or Fortran,
@@ -622,7 +622,7 @@ def __hash__(self):
         return hash(id(self.variable))
 
 #------------------------------------------------------------------------------
-class CodeBlock(Basic):
+class CodeBlock(PyccelAstNode):
 
     """Represents a list of stmt for code generation.
        we use it when a single statement in python
@@ -705,7 +705,7 @@ def set_fst(self, fst):
             if not l.fst:
                 l.set_fst(fst)
 
-class AliasAssign(Basic):
+class AliasAssign(PyccelAstNode):
 
     """Represents aliasing for code generation. An alias is any statement of the
     form `lhs := rhs` where
@@ -758,7 +758,7 @@ def rhs(self):
         return self._rhs
 
 
-class SymbolicAssign(Basic):
+class SymbolicAssign(PyccelAstNode):
 
     """Represents symbolic aliasing for code generation. An alias is any statement of the
     form `lhs := rhs` where
@@ -805,7 +805,7 @@ class AugAssign(Assign):
 
     Parameters
     ----------
-    lhs : PyccelAstNode
+    lhs : TypedAstNode
         In the syntactic stage:
            Object representing the lhs of the expression. These should be
            singular objects, such as one would use in writing code. Notable types
@@ -817,11 +817,11 @@ class AugAssign(Assign):
     op : str
         Operator (+, -, /, \*, %).
 
-    rhs : PyccelAstNode
+    rhs : TypedAstNode
         In the syntactic stage:
           Object representing the rhs of the expression
         In the semantic stage :
-          PyccelAstNode with the same shape as the lhs
+          TypedAstNode with the same shape as the lhs
 
     status: None, str
         if lhs is not allocatable, then status is None.
@@ -889,7 +889,7 @@ def to_basic_assign(self):
                 like   = self.like)
 
 
-class While(ScopedNode):
+class While(ScopedAstNode):
 
     """Represents a 'while' statement in the code.
 
@@ -899,7 +899,7 @@ class While(ScopedNode):
 
     Parameters
     ----------
-    test : PyccelAstNode
+    test : TypedAstNode
         test condition given as an expression
     body : list of Pyccel objects
         list of statements representing the body of the While statement.
@@ -946,7 +946,7 @@ def local_vars(self):
         return tuple(self.scope.variables.values())
 
 
-class With(ScopedNode):
+class With(ScopedAstNode):
 
     """Represents a 'with' statement in the code.
 
@@ -956,7 +956,7 @@ class With(ScopedNode):
 
     Parameters
     ----------
-    test : PyccelAstNode
+    test : TypedAstNode
         with definition statement given as an expression
     body : list of Pyccel objects
         list of statements representing the body of the With statement.
@@ -1015,7 +1015,7 @@ def block(self):
 
 # TODO add a name to a block?
 
-class Block(ScopedNode):
+class Block(ScopedAstNode):
 
     """Represents a block in the code. A block consists of the following inputs
 
@@ -1081,7 +1081,7 @@ def declarations(self):
 
 
 
-class Module(ScopedNode):
+class Module(ScopedAstNode):
     """
     Represents a module in the code.
 
@@ -1351,7 +1351,7 @@ def keys(self):
         """
         return self._internal_dictionary.keys()
 
-class ModuleHeader(Basic):
+class ModuleHeader(PyccelAstNode):
     """
     Represents the header file for a module.
 
@@ -1407,7 +1407,7 @@ def __init__(self, module):
     def module(self):
         return self._module
 
-class Program(ScopedNode):
+class Program(ScopedAstNode):
 
     """Represents a Program in the code. A block consists of the following inputs
 
@@ -1494,7 +1494,7 @@ def remove_import(self, name):
 
 
 #==============================================================================
-class Iterable(Basic):
+class Iterable(PyccelAstNode):
     """
     Wrapper around iterable types helping to convert between those
     types and a range (necessary in low level languages, e.g. C and Fortran)
@@ -1620,7 +1620,7 @@ def loop_counters(self):
 
 #==============================================================================
 
-class For(ScopedNode):
+class For(ScopedAstNode):
 
     """Represents a 'for-loop' in the code.
 
@@ -1767,13 +1767,13 @@ def depth(self):
     def ranges(self):
         return get_iterable_ranges(self.iterable)
 
-class FunctionCallArgument(Basic):
+class FunctionCallArgument(PyccelAstNode):
     """
     An argument passed in a function call
 
     Parameters
     ---------
-    value   : PyccelAstNode
+    value   : TypedAstNode
               The expression passed as an argument
     keyword : str
               If the argument is passed by keyword then this
@@ -1816,7 +1816,7 @@ def __str__(self):
         else:
             return '{}'.format(str(self.value))
 
-class FunctionDefArgument(PyccelAstNode):
+class FunctionDefArgument(TypedAstNode):
     """
     Node describing the argument of a function.
 
@@ -1829,7 +1829,7 @@ class FunctionDefArgument(PyccelAstNode):
     name : PyccelSymbol, Variable, FunctionAddress
         The name of the argument.
 
-    value : PyccelAstNode, default: None
+    value : TypedAstNode, default: None
         The default value of the argument.
 
     kwonly : bool
@@ -1955,7 +1955,7 @@ def __repr__(self):
         else:
             return 'FunctionDefArgument({})'.format(repr(self.name))
 
-class FunctionDefResult(PyccelAstNode):
+class FunctionDefResult(TypedAstNode):
     """
     Node describing the result of a function.
 
@@ -2036,7 +2036,7 @@ def __repr__(self):
     def __str__(self):
         return str(self.var)
 
-class FunctionCall(PyccelAstNode):
+class FunctionCall(TypedAstNode):
     """
     Represents a function call in the code.
 
@@ -2121,7 +2121,7 @@ def __init__(self, func, args, current_function=None):
                 if isinstance(av, FunctionDef) else a for a, av in zip(args, arg_vals)]
 
         if current_function == func.name:
-            if len(func.results)>0 and not isinstance(func.results[0], PyccelAstNode):
+            if len(func.results)>0 and not isinstance(func.results[0], TypedAstNode):
                 errors.report(RECURSIVE_RESULTS_REQUIRED, symbol=func, severity="fatal")
 
         self._funcdef       = func
@@ -2188,7 +2188,7 @@ class DottedFunctionCall(FunctionCall):
                        The definition of the function being called
     args             : tuple
                        The arguments being passed to the function
-    prefix           : PyccelAstNode
+    prefix           : TypedAstNode
                        The object in which the function is defined
                        E.g. for a.f()
                        prefix will contain a
@@ -2267,13 +2267,13 @@ def cls_variable(self):
         return self._cls_variable
 
 
-class Return(Basic):
+class Return(PyccelAstNode):
 
     """Represents a function return in the code.
 
     Parameters
     ----------
-    expr : PyccelAstNode
+    expr : TypedAstNode
         The expression to return.
 
     stmts :represent assign stmts in the case of expression return
@@ -2312,7 +2312,7 @@ def __repr__(self):
             code = ''
         return code+"Return({})".format(','.join([repr(e) for e in self.expr]))
 
-class FunctionDef(ScopedNode):
+class FunctionDef(ScopedAstNode):
 
     """
     Represents a function definition.
@@ -2940,7 +2940,7 @@ class PyccelFunctionDef(FunctionDef):
     name : str
         The name of the function.
 
-    func_class : type inheriting from PyccelInternalFunction / PyccelAstNode
+    func_class : type inheriting from PyccelInternalFunction / TypedAstNode
         The class which should be instantiated upon a FunctionCall
         to this FunctionDef object.
 
@@ -2956,7 +2956,7 @@ class PyccelFunctionDef(FunctionDef):
     __slots__ = ('_argument_description',)
     def __init__(self, name, func_class, *, decorators = {}, argument_description = {}):
         assert isinstance(func_class, type) and \
-                issubclass(func_class, (PyccelInternalFunction, PyccelAstNode))
+                issubclass(func_class, (PyccelInternalFunction, TypedAstNode))
         assert isinstance(argument_description, dict)
         arguments = ()
         results = ()
@@ -2976,7 +2976,7 @@ def argument_description(self):
         """
         return self._argument_description
 
-class Interface(Basic):
+class Interface(PyccelAstNode):
 
     """Represents an Interface.
 
@@ -3180,7 +3180,7 @@ class SympyFunction(FunctionDef):
 
 
 
-class ClassDef(ScopedNode):
+class ClassDef(ScopedAstNode):
     """
     Represents a class definition.
 
@@ -3554,7 +3554,7 @@ def is_unused(self):
         return False
 
 
-class Import(Basic):
+class Import(PyccelAstNode):
 
     """Represents inclusion of dependencies in the code.
 
@@ -3690,7 +3690,7 @@ def source_module(self):
 
 # TODO: Should Declare have an optional init value for each var?
 
-class FuncAddressDeclare(Basic):
+class FuncAddressDeclare(PyccelAstNode):
 
     """Represents a FunctionAddress declaration in the code.
 
@@ -3700,7 +3700,7 @@ class FuncAddressDeclare(Basic):
         An instance of FunctionAddress.
     intent: None, str
         one among {'in', 'out', 'inout'}
-    value: PyccelAstNode
+    value: TypedAstNode
         variable value
     static: bool
         True for a static declaration of an array.
@@ -3768,7 +3768,7 @@ def static(self):
         return self._static
 
 # ARA : issue-999 add is_external for external function exported through header files
-class Declare(Basic):
+class Declare(PyccelAstNode):
 
     """Represents a variable declaration in the code.
 
@@ -3781,7 +3781,7 @@ class Declare(Basic):
         Variables must be of the same type.
     intent: None, str
         one among {'in', 'out', 'inout'}
-    value: PyccelAstNode
+    value: TypedAstNode
         variable value
     static: bool
         True for a static declaration of an array.
@@ -3890,21 +3890,21 @@ def module_variable(self):
     def __repr__(self):
         return 'Declare({})'.format(repr(self.variable))
 
-class Break(Basic):
+class Break(PyccelAstNode):
 
     """Represents a break in the code."""
     __slots__ = ()
     _attribute_nodes = ()
 
 
-class Continue(Basic):
+class Continue(PyccelAstNode):
 
     """Represents a continue in the code."""
     __slots__ = ()
     _attribute_nodes = ()
 
 
-class Raise(Basic):
+class Raise(PyccelAstNode):
 
     """Represents a raise in the code."""
     __slots__ = ()
@@ -3912,13 +3912,13 @@ class Raise(Basic):
 
 
 
-class SymbolicPrint(Basic):
+class SymbolicPrint(PyccelAstNode):
 
     """Represents a print function of symbolic expressions in the code.
 
     Parameters
     ----------
-    expr : PyccelAstNode
+    expr : TypedAstNode
         The expression to print
 
     Examples
@@ -3950,7 +3950,7 @@ def expr(self):
         return self._expr
 
 
-class Del(Basic):
+class Del(PyccelAstNode):
 
     """Represents a memory deallocation in the code.
 
@@ -3984,7 +3984,7 @@ def variables(self):
         return self._variables
 
 
-class EmptyNode(Basic):
+class EmptyNode(PyccelAstNode):
     """
     Represents an empty node in the abstract syntax tree (AST).
     When a subtree is removed from the AST, we replace it with an EmptyNode
@@ -4010,7 +4010,7 @@ def __str__(self):
         return ''
 
 
-class Comment(Basic):
+class Comment(PyccelAstNode):
 
     """Represents a Comment in the code.
 
@@ -4082,7 +4082,7 @@ def __init__(self, n):
         text = """.""" * n
         super().__init__(text)
 
-class AnnotatedComment(Basic):
+class AnnotatedComment(PyccelAstNode):
 
     """Represents a Annotated Comment in the code.
 
@@ -4122,7 +4122,7 @@ def __getnewargs__(self):
         args = (self.accel, self.txt)
         return args
 
-class CommentBlock(Basic):
+class CommentBlock(PyccelAstNode):
 
     """ Represents a Block of Comments
 
@@ -4158,13 +4158,13 @@ def header(self, header):
         self._header = header
 
 
-class Assert(Basic):
+class Assert(PyccelAstNode):
     """
     Represents an assert statement in the code.
 
     Parameters
     ----------
-    test: PyccelAstNode
+    test: TypedAstNode
         boolean expression to check
     """
     __slots__ = ('_test',)
@@ -4182,13 +4182,13 @@ def test(self):
         return self._test
 
 
-class Pass(Basic):
+class Pass(PyccelAstNode):
 
     """Basic class for pass instruction."""
     __slots__ = ()
     _attribute_nodes = ()
 
-class Exit(Basic):
+class Exit(PyccelAstNode):
 
     """Basic class for exits."""
     __slots__ = ()
@@ -4200,13 +4200,13 @@ class ErrorExit(Exit):
     """Exit with error."""
     __slots__ = ()
 
-class IfSection(Basic):
+class IfSection(PyccelAstNode):
     """Represents a condition and associated code block
     in an if statement in the code.
 
     Parameters
     ----------
-    cond : PyccelAstNode
+    cond : TypedAstNode
            A boolean expression indicating whether or not the block
            should be executed
     body : CodeBlock
@@ -4253,7 +4253,7 @@ def __iter__(self):
     def __str__(self):
         return "IfSec({},{})".format(str(self.condition), str(self.body))
 
-class If(Basic):
+class If(PyccelAstNode):
 
     """Represents a if statement in the code.
 
@@ -4297,7 +4297,7 @@ def bodies(self):
     def __str__(self):
         return "If({})".format(','.join(str(b) for b in self.blocks))
 
-class StarredArguments(Basic):
+class StarredArguments(PyccelAstNode):
     __slots__ = ('_starred_obj',)
     _attribute_nodes = ('_starred_obj',)
     def __init__(self, args):
@@ -4310,7 +4310,7 @@ def args_var(self):
 
 # ...
 
-class InProgram(PyccelAstNode):
+class InProgram(TypedAstNode):
     """
     Class representing the boolean:
     __name__ == '__main__'
@@ -4325,7 +4325,7 @@ class InProgram(PyccelAstNode):
 
 # ...
 
-class Decorator(Basic):
+class Decorator(PyccelAstNode):
     """ Class representing a function decorator.
     For now this is just designed to handle the pyccel decorators
 
diff --git a/pyccel/ast/cwrapper.py b/pyccel/ast/cwrapper.py
index 32b5b978e2..e00952d3a3 100644
--- a/pyccel/ast/cwrapper.py
+++ b/pyccel/ast/cwrapper.py
@@ -11,7 +11,7 @@
 from ..errors.errors import Errors
 from ..errors.messages import PYCCEL_RESTRICTION_TODO
 
-from .basic     import Basic, PyccelAstNode
+from .basic     import PyccelAstNode, TypedAstNode
 
 from .datatypes import DataType, default_precision
 from .datatypes import NativeInteger, NativeFloat, NativeComplex
@@ -72,7 +72,7 @@ class used to hold Python objects in `Python.h`.
 #-------------------------------------------------------------------
 
 #TODO: Is there an equivalent to static so this can be a static list of strings?
-class PyArgKeywords(Basic):
+class PyArgKeywords(PyccelAstNode):
     """
     Represents the list containing the names of all arguments to a function.
     This information allows the function to be called by keyword
@@ -106,7 +106,7 @@ def arg_names(self):
         return self._arg_names
 
 #-------------------------------------------------------------------
-class PyArg_ParseTupleNode(Basic):
+class PyArg_ParseTupleNode(PyccelAstNode):
     """
     Represents a call to the function `PyArg_ParseTupleNode`.
 
@@ -198,7 +198,7 @@ def arg_names(self):
         return self._arg_names
 
 #-------------------------------------------------------------------
-class PyBuildValueNode(PyccelAstNode):
+class PyBuildValueNode(TypedAstNode):
     """
     Represents a call to the function PyBuildValueNode.
 
@@ -236,7 +236,7 @@ def args(self):
         return self._result_args
 
 #-------------------------------------------------------------------
-class PyModule_AddObject(PyccelAstNode):
+class PyModule_AddObject(TypedAstNode):
     """
     Represents a call to the PyModule_AddObject function.
 
diff --git a/pyccel/ast/functionalexpr.py b/pyccel/ast/functionalexpr.py
index 9026afba17..b767bc0716 100644
--- a/pyccel/ast/functionalexpr.py
+++ b/pyccel/ast/functionalexpr.py
@@ -7,7 +7,7 @@
 
 from pyccel.utilities.stage import PyccelStage
 
-from .basic import PyccelAstNode
+from .basic import TypedAstNode
 
 pyccel_stage = PyccelStage()
 
@@ -20,7 +20,7 @@
 )
 
 #==============================================================================
-class FunctionalFor(PyccelAstNode):
+class FunctionalFor(TypedAstNode):
 
     """
     Represents any generator expression e.g:
@@ -30,7 +30,7 @@ class FunctionalFor(PyccelAstNode):
     ----------
     loops   : CodeBlock/For
               The loops contained in the expression
-    expr    : Basic
+    expr    : PyccelAstNode
               The expression at the origin of the expression
               E.g. 'i' for '[i for i in range(10)]'
     lhs     : Variable
diff --git a/pyccel/ast/headers.py b/pyccel/ast/headers.py
index 7b3be5c894..c5a9a9ebcb 100644
--- a/pyccel/ast/headers.py
+++ b/pyccel/ast/headers.py
@@ -7,7 +7,7 @@
 from pyccel.utilities.strings import create_incremented_string
 from ..errors.errors    import Errors
 from ..errors.messages  import TEMPLATE_IN_UNIONTYPE
-from .basic             import Basic, iterable
+from .basic             import PyccelAstNode, iterable
 from .core              import Assign, FunctionCallArgument
 from .core              import FunctionDef, FunctionCall, FunctionAddress
 from .core              import FunctionDefArgument, FunctionDefResult
@@ -32,7 +32,7 @@
 errors = Errors()
 
 #==============================================================================
-class Header(Basic):
+class Header(PyccelAstNode):
     __slots__ = ()
     _attribute_nodes = ()
 
diff --git a/pyccel/ast/internals.py b/pyccel/ast/internals.py
index 6efe5d4201..10af322a85 100644
--- a/pyccel/ast/internals.py
+++ b/pyccel/ast/internals.py
@@ -11,7 +11,7 @@
 from operator import attrgetter
 from pyccel.utilities.stage import PyccelStage
 
-from .basic     import Basic, PyccelAstNode, Immutable
+from .basic     import PyccelAstNode, TypedAstNode, Immutable
 from .datatypes import NativeInteger, default_precision
 from .literals  import LiteralInteger
 
@@ -30,7 +30,7 @@
 )
 
 
-class PyccelInternalFunction(PyccelAstNode):
+class PyccelInternalFunction(TypedAstNode):
     """
     Abstract class for function calls translated to Pyccel objects.
 
@@ -80,7 +80,7 @@ class PyccelArraySize(PyccelInternalFunction):
 
     Parameters
     ----------
-    arg : PyccelAstNode
+    arg : TypedAstNode
         An array of unknown size.
     """
     __slots__ = ()
@@ -124,7 +124,7 @@ class PyccelArrayShapeElement(PyccelInternalFunction):
 
     Parameters
     ----------
-    arg : PyccelAstNode
+    arg : TypedAstNode
         An array of unknown shape.
 
     index : int
@@ -140,12 +140,12 @@ class PyccelArrayShapeElement(PyccelInternalFunction):
     _order = None
 
     def __init__(self, arg, index):
-        if not isinstance(arg, PyccelAstNode):
+        if not isinstance(arg, TypedAstNode):
             raise TypeError(f'Unknown type {type(arg)} of {arg}.')
 
         if isinstance(index, int):
             index = LiteralInteger(index)
-        elif not isinstance(index, PyccelAstNode):
+        elif not isinstance(index, TypedAstNode):
             raise TypeError(f'Unknown type {type(index)} of {index}.')
 
         super().__init__(arg, index)
@@ -180,7 +180,7 @@ def __eq__(self, other):
             return False
 
 
-class Slice(Basic):
+class Slice(PyccelAstNode):
     """
     Represents a slice in the code.
 
@@ -324,7 +324,7 @@ def is_temp(self):
         """
         return self._is_temp
 
-class AnnotatedPyccelSymbol(Basic):
+class AnnotatedPyccelSymbol(PyccelAstNode):
     """
     Class representing a symbol in the code which has an annotation.
 
@@ -371,13 +371,13 @@ def annotation(self):
         """
         return self._annotation
 
-class PrecomputedCode(Basic):
+class PrecomputedCode(PyccelAstNode):
     """
     Internal helper class for storing code which must be defined by the printer
     before it is needed chronologically (e.g. for inline functions as arguments
     to the same function).
     This class should be avoided if at all possible as it may break code which
-    searches through attribute nodes, where possible use Basic's methods,
+    searches through attribute nodes, where possible use PyccelAstNode's methods,
     e.g. substitute
 
     Parameters
@@ -439,7 +439,7 @@ def max_precision(objs : list, allow_native : bool = True):
     Parameters
     ----------
     objs : list
-       A list of PyccelAstNodes.
+       A list of TypedAstNodes.
 
     allow_native : bool, default=True
         Allow the final result to be a native precision (i.e. -1).
@@ -470,7 +470,7 @@ def get_final_precision(obj):
 
     Parameters
     ----------
-    obj : PyccelAstNode
+    obj : TypedAstNode
         The object whose precision we want to investigate.
 
     Returns
diff --git a/pyccel/ast/literals.py b/pyccel/ast/literals.py
index 0a3a6ad5d1..e874fa59a2 100644
--- a/pyccel/ast/literals.py
+++ b/pyccel/ast/literals.py
@@ -6,7 +6,7 @@
 """
 from pyccel.utilities.metaclasses import Singleton
 
-from .basic              import PyccelAstNode, Basic
+from .basic              import TypedAstNode, PyccelAstNode
 from .datatypes          import (NativeGeneric, NativeInteger, NativeBool, NativeFloat,
                                   NativeComplex, NativeString)
 
@@ -25,7 +25,7 @@
 )
 
 #------------------------------------------------------------------------------
-class Literal(PyccelAstNode):
+class Literal(TypedAstNode):
     """
     Represents a python literal
     This class is abstract and should be implemented for each dtype
@@ -42,7 +42,7 @@ def __init__(self, precision):
         self._precision = precision
         super().__init__()
 
-    @PyccelAstNode.precision.setter
+    @TypedAstNode.precision.setter
     def precision(self, precision):
         """ Set precision for a literal class"""
         self._precision = precision
@@ -58,7 +58,7 @@ def __str__(self):
         return str(self.python_value)
 
     def __eq__(self, other):
-        if isinstance(other, PyccelAstNode):
+        if isinstance(other, TypedAstNode):
             return isinstance(other, type(self)) and self.python_value == other.python_value
         else:
             return self.python_value == other
@@ -225,7 +225,7 @@ def python_value(self):
 
 #------------------------------------------------------------------------------
 
-class Nil(PyccelAstNode, metaclass=Singleton):
+class Nil(TypedAstNode, metaclass=Singleton):
 
     """
     class for None object in the code.
@@ -252,7 +252,7 @@ def __hash__(self):
 
 #------------------------------------------------------------------------------
 
-class NilArgument(Basic):
+class NilArgument(PyccelAstNode):
     """Represents the python value None when passed as an argument
     to an inline function. This class is necessary as to avoid
     accidental substitution due to Singletons"""
diff --git a/pyccel/ast/macros.py b/pyccel/ast/macros.py
index 4645491127..9b4bd3dee4 100644
--- a/pyccel/ast/macros.py
+++ b/pyccel/ast/macros.py
@@ -9,7 +9,7 @@
 """
 from pyccel.utilities.stage import PyccelStage
 
-from .basic          import PyccelAstNode
+from .basic          import TypedAstNode
 from .datatypes      import NativeInteger, NativeGeneric
 from .internals      import PyccelSymbol
 from .variable       import Variable
@@ -25,7 +25,7 @@
 )
 
 #==============================================================================
-class Macro(PyccelAstNode):
+class Macro(TypedAstNode):
     """."""
     __slots__ = ('_argument',)
     _name = '__UNDEFINED__'
diff --git a/pyccel/ast/mathext.py b/pyccel/ast/mathext.py
index 3d2a42b5a5..65d321a7cb 100644
--- a/pyccel/ast/mathext.py
+++ b/pyccel/ast/mathext.py
@@ -116,7 +116,7 @@ class MathAcos(MathFunctionFloat):
 
     Parameters
     ----------
-    x : PyccelAstNode
+    x : TypedAstNode
         The expression passed as argument to the function.
     """
     __slots__ = ()
@@ -131,7 +131,7 @@ class MathAcosh(MathFunctionFloat):
 
     Parameters
     ----------
-    x : PyccelAstNode
+    x : TypedAstNode
         The expression passed as argument to the function.
     """
     __slots__ = ()
@@ -146,7 +146,7 @@ class MathAsin(MathFunctionFloat):
 
     Parameters
     ----------
-    x : PyccelAstNode
+    x : TypedAstNode
         The expression passed as argument to the function.
     """
     __slots__ = ()
@@ -161,7 +161,7 @@ class MathAsinh(MathFunctionFloat):
 
     Parameters
     ----------
-    x : PyccelAstNode
+    x : TypedAstNode
         The expression passed as argument to the function.
     """
     __slots__ = ()
@@ -176,7 +176,7 @@ class MathAtan(MathFunctionFloat):
 
     Parameters
     ----------
-    x : PyccelAstNode
+    x : TypedAstNode
         The expression passed as argument to the function.
     """
     __slots__ = ()
@@ -191,9 +191,9 @@ class MathAtan2   (MathFunctionFloat):
 
     Parameters
     ----------
-    y : PyccelAstNode
+    y : TypedAstNode
         The first expression passed as argument to the function.
-    x : PyccelAstNode
+    x : TypedAstNode
         The second expression passed as argument to the function.
     """
     __slots__ = ()
@@ -208,7 +208,7 @@ class MathAtanh(MathFunctionFloat):
 
     Parameters
     ----------
-    x : PyccelAstNode
+    x : TypedAstNode
         The expression passed as argument to the function.
     """
     __slots__ = ()
@@ -223,7 +223,7 @@ class MathCopysign(MathFunctionFloat):
 
     Parameters
     ----------
-    x : PyccelAstNode
+    x : TypedAstNode
         The expression passed as argument to the function.
     """
     __slots__ = ()
@@ -238,7 +238,7 @@ class MathCos(MathFunctionFloat):
 
     Parameters
     ----------
-    x : PyccelAstNode
+    x : TypedAstNode
         The expression passed as argument to the function.
     """
     __slots__ = ()
@@ -253,7 +253,7 @@ class MathCosh(MathFunctionFloat):
 
     Parameters
     ----------
-    x : PyccelAstNode
+    x : TypedAstNode
         The expression passed as argument to the function.
     """
     __slots__ = ()
@@ -268,7 +268,7 @@ class MathErf(MathFunctionFloat):
 
     Parameters
     ----------
-    x : PyccelAstNode
+    x : TypedAstNode
         The expression passed as argument to the function.
     """
     __slots__ = ()
@@ -283,7 +283,7 @@ class MathErfc(MathFunctionFloat):
 
     Parameters
     ----------
-    x : PyccelAstNode
+    x : TypedAstNode
         The expression passed as argument to the function.
     """
     __slots__ = ()
@@ -298,7 +298,7 @@ class MathExp(MathFunctionFloat):
 
     Parameters
     ----------
-    x : PyccelAstNode
+    x : TypedAstNode
         The expression passed as argument to the function.
     """
     __slots__ = ()
@@ -319,7 +319,7 @@ class MathFabs(MathFunctionFloat):
 
     Parameters
     ----------
-    x : PyccelAstNode
+    x : TypedAstNode
         The expression passed as argument to the function.
     """
     __slots__ = ()
@@ -334,7 +334,7 @@ class MathFmod(MathFunctionFloat):
 
     Parameters
     ----------
-    x : PyccelAstNode
+    x : TypedAstNode
         The expression passed as argument to the function.
     """
     __slots__ = ()
@@ -349,7 +349,7 @@ class MathFsum(MathFunctionFloat):
 
     Parameters
     ----------
-    x : PyccelAstNode
+    x : TypedAstNode
         The expression passed as argument to the function.
     """
     __slots__ = ()
@@ -364,7 +364,7 @@ class MathGamma(MathFunctionFloat):
 
     Parameters
     ----------
-    x : PyccelAstNode
+    x : TypedAstNode
         The expression passed as argument to the function.
     """
     __slots__ = ()
@@ -379,7 +379,7 @@ class MathHypot(MathFunctionFloat):
 
     Parameters
     ----------
-    x : PyccelAstNode
+    x : TypedAstNode
         The expression passed as argument to the function.
     """
     __slots__ = ()
@@ -394,7 +394,7 @@ class MathLdexp(MathFunctionFloat):
 
     Parameters
     ----------
-    x : PyccelAstNode
+    x : TypedAstNode
         The expression passed as argument to the function.
     """
     __slots__ = ()
@@ -409,7 +409,7 @@ class MathLgamma(MathFunctionFloat):
 
     Parameters
     ----------
-    x : PyccelAstNode
+    x : TypedAstNode
         The expression passed as argument to the function.
     """
     __slots__ = ()
@@ -424,7 +424,7 @@ class MathLog(MathFunctionFloat):
 
     Parameters
     ----------
-    x : PyccelAstNode
+    x : TypedAstNode
         The expression passed as argument to the function.
     """
     __slots__ = ()
@@ -439,7 +439,7 @@ class MathLog10   (MathFunctionFloat):
 
     Parameters
     ----------
-    x : PyccelAstNode
+    x : TypedAstNode
         The expression passed as argument to the function.
     """
     __slots__ = ()
@@ -454,7 +454,7 @@ class MathLog1p   (MathFunctionFloat):
 
     Parameters
     ----------
-    x : PyccelAstNode
+    x : TypedAstNode
         The expression passed as argument to the function.
     """
     __slots__ = ()
@@ -469,7 +469,7 @@ class MathLog2    (MathFunctionFloat):
 
     Parameters
     ----------
-    x : PyccelAstNode
+    x : TypedAstNode
         The expression passed as argument to the function.
     """
     __slots__ = ()
@@ -484,7 +484,7 @@ class MathPow(MathFunctionFloat):
 
     Parameters
     ----------
-    x : PyccelAstNode
+    x : TypedAstNode
         The expression passed as argument to the function.
     """
     __slots__ = ()
@@ -499,7 +499,7 @@ class MathSin(MathFunctionFloat):
 
     Parameters
     ----------
-    x : PyccelAstNode
+    x : TypedAstNode
         The expression passed as argument to the function.
     """
     __slots__ = ()
@@ -514,7 +514,7 @@ class MathSinh(MathFunctionFloat):
 
     Parameters
     ----------
-    x : PyccelAstNode
+    x : TypedAstNode
         The expression passed as argument to the function.
     """
     __slots__ = ()
@@ -529,7 +529,7 @@ class MathSqrt(MathFunctionFloat):
 
     Parameters
     ----------
-    x : PyccelAstNode
+    x : TypedAstNode
         The expression passed as argument to the function.
     """
     __slots__ = ()
@@ -544,7 +544,7 @@ class MathTan(MathFunctionFloat):
 
     Parameters
     ----------
-    x : PyccelAstNode
+    x : TypedAstNode
         The expression passed as argument to the function.
     """
     __slots__ = ()
@@ -559,7 +559,7 @@ class MathTanh(MathFunctionFloat):
 
     Parameters
     ----------
-    x : PyccelAstNode
+    x : TypedAstNode
         The expression passed as argument to the function.
     """
     __slots__ = ()
@@ -574,7 +574,7 @@ class MathRemainder(MathFunctionFloat):
 
     Parameters
     ----------
-    x : PyccelAstNode
+    x : TypedAstNode
         The expression passed as argument to the function.
     """
     __slots__ = ()
@@ -588,7 +588,7 @@ class MathRadians(MathFunctionFloat):
 
     Parameters
     ----------
-    x : PyccelAstNode
+    x : TypedAstNode
         The expression passed as argument to the function.
     """
     __slots__ = ()
@@ -603,7 +603,7 @@ class MathDegrees(MathFunctionFloat):
 
     Parameters
     ----------
-    x : PyccelAstNode
+    x : TypedAstNode
         The expression passed as argument to the function.
     """
     __slots__ = ()
@@ -618,7 +618,7 @@ class MathFactorial(MathFunctionInt):
 
     Parameters
     ----------
-    x : PyccelAstNode
+    x : TypedAstNode
         The expression passed as argument to the function.
     """
     __slots__ = ()
@@ -633,7 +633,7 @@ class MathGcd(MathFunctionInt):
 
     Parameters
     ----------
-    x : PyccelAstNode
+    x : TypedAstNode
         The expression passed as argument to the function.
     """
     __slots__ = ()
@@ -648,7 +648,7 @@ class MathLcm(MathFunctionInt):
 
     Parameters
     ----------
-    x : PyccelAstNode
+    x : TypedAstNode
         The expression passed as argument to the function.
     """
     __slots__ = ()
@@ -662,7 +662,7 @@ class MathCeil(MathFunctionInt):
 
     Parameters
     ----------
-    x : PyccelAstNode
+    x : TypedAstNode
         The expression passed as argument to the function.
     """
     __slots__ = ()
@@ -677,7 +677,7 @@ class MathFloor(MathFunctionInt):
 
     Parameters
     ----------
-    x : PyccelAstNode
+    x : TypedAstNode
         The expression passed as argument to the function.
     """
     __slots__ = ()
@@ -692,7 +692,7 @@ class MathTrunc(MathFunctionInt):
 
     Parameters
     ----------
-    x : PyccelAstNode
+    x : TypedAstNode
         The expression passed as argument to the function.
     """
     __slots__ = ()
@@ -707,7 +707,7 @@ class MathIsclose(MathFunctionBool):
 
     Parameters
     ----------
-    x : PyccelAstNode
+    x : TypedAstNode
         The expression passed as argument to the function.
     """
     __slots__ = ()
@@ -722,7 +722,7 @@ class MathIsfinite(MathFunctionBool):
 
     Parameters
     ----------
-    x : PyccelAstNode
+    x : TypedAstNode
         The expression passed as argument to the function.
     """
     __slots__ = ()
@@ -737,7 +737,7 @@ class MathIsinf(MathFunctionBool):
 
     Parameters
     ----------
-    x : PyccelAstNode
+    x : TypedAstNode
         The expression passed as argument to the function.
     """
     __slots__ = ()
@@ -752,7 +752,7 @@ class MathIsnan(MathFunctionBool):
 
     Parameters
     ----------
-    x : PyccelAstNode
+    x : TypedAstNode
         The expression passed as argument to the function.
     """
     __slots__ = ()
diff --git a/pyccel/ast/numpyext.py b/pyccel/ast/numpyext.py
index c48b891d12..029c53b267 100644
--- a/pyccel/ast/numpyext.py
+++ b/pyccel/ast/numpyext.py
@@ -14,7 +14,7 @@
 
 from pyccel.utilities.stage import PyccelStage
 
-from .basic          import PyccelAstNode
+from .basic          import TypedAstNode
 from .builtins       import (PythonInt, PythonBool, PythonFloat, PythonTuple,
                              PythonComplex, PythonReal, PythonImag, PythonList,
                              PythonType, PythonConjugate)
@@ -124,7 +124,7 @@ def process_shape(is_scalar, shape):
     ----------
     is_scalar : bool
                 True if the result is a scalar, False if it is an array
-    shape     : PyccelAstNode/iterable/int
+    shape     : TypedAstNode/iterable/int
                 input shape
     """
     if is_scalar:
@@ -136,12 +136,12 @@ def process_shape(is_scalar, shape):
 
     new_shape = []
     for s in shape:
-        if isinstance(s,(LiteralInteger, Variable, Slice, PyccelAstNode, FunctionCall)):
+        if isinstance(s,(LiteralInteger, Variable, Slice, TypedAstNode, FunctionCall)):
             new_shape.append(s)
         elif isinstance(s, int):
             new_shape.append(LiteralInteger(s))
         else:
-            raise TypeError('shape elements cannot be '+str(type(s))+'. They must be one of the following types: LiteralInteger, Variable, Slice, PyccelAstNode, int, FunctionCall')
+            raise TypeError('shape elements cannot be '+str(type(s))+'. They must be one of the following types: LiteralInteger, Variable, Slice, TypedAstNode, int, FunctionCall')
     return tuple(new_shape)
 
 #=======================================================================================
@@ -350,7 +350,7 @@ class NumpyResultType(PyccelInternalFunction):
 
     Parameters
     ----------
-    *arrays_and_dtypes : PyccelAstNode
+    *arrays_and_dtypes : TypedAstNode
         Any arrays and dtypes passed to the function (currently only accepts one array
         and no dtypes).
     """
@@ -466,7 +466,7 @@ class NumpyNewArray(PyccelInternalFunction):
 
     Parameters
     ----------
-    *args : tuple of PyccelAstNode
+    *args : tuple of TypedAstNode
         The arguments of the superclass PyccelInternalFunction.
     init_dtype : PythonType, PyccelFunctionDef, LiteralString, str
         The actual dtype passed to the NumPy function.
@@ -682,7 +682,7 @@ class NumpySum(PyccelInternalFunction):
     _order = None
 
     def __init__(self, arg):
-        if not isinstance(arg, PyccelAstNode):
+        if not isinstance(arg, TypedAstNode):
             raise TypeError('Unknown type of  %s.' % type(arg))
         super().__init__(arg)
         if isinstance(arg.dtype, NativeBool):
@@ -714,7 +714,7 @@ class NumpyProduct(PyccelInternalFunction):
     _order = None
 
     def __init__(self, arg):
-        if not isinstance(arg, PyccelAstNode):
+        if not isinstance(arg, TypedAstNode):
             raise TypeError('Unknown type of  %s.' % type(arg))
         super().__init__(arg)
         self._arg = PythonList(arg) if arg.rank == 0 else self._args[0]
@@ -738,9 +738,9 @@ class NumpyMatmul(PyccelInternalFunction):
 
     Parameters
     ----------
-    a : PyccelAstNode
+    a : TypedAstNode
         The first argument of the matrix multiplication.
-    b : PyccelAstNode
+    b : TypedAstNode
         The second argument of the matrix multiplication.
     """
     __slots__ = ('_dtype','_precision','_shape','_rank','_order')
@@ -751,9 +751,9 @@ def __init__(self, a ,b):
         if pyccel_stage == 'syntactic':
             return
 
-        if not isinstance(a, PyccelAstNode):
+        if not isinstance(a, TypedAstNode):
             raise TypeError('Unknown type of  %s.' % type(a))
-        if not isinstance(b, PyccelAstNode):
+        if not isinstance(b, TypedAstNode):
             raise TypeError('Unknown type of  %s.' % type(a))
 
         args      = (a, b)
@@ -803,7 +803,7 @@ class constructor always returns a PythonTuple with the required shape.
 
     Parameters
     ----------
-    arg : PyccelAstNode
+    arg : TypedAstNode
         The Numpy array whose shape is being investigated.
 
     Returns
@@ -864,7 +864,7 @@ def __init__(self, start, stop, num=None, endpoint=True, dtype=None):
         if num.rank != 0 or not isinstance(num.dtype, NativeInteger):
             raise TypeError('Expecting positive integer num argument.')
 
-        if any(not isinstance(arg, PyccelAstNode) for arg in (start, stop, num)):
+        if any(not isinstance(arg, TypedAstNode) for arg in (start, stop, num)):
             raise TypeError('Expecting valid args.')
 
         init_dtype = dtype
@@ -973,13 +973,13 @@ class NumpyWhere(PyccelInternalFunction):
 
     Parameters
     ----------
-    condition : PyccelAstNode
+    condition : TypedAstNode
         The condition which determines which value is returned.
 
-    x : PyccelAstNode, optional
+    x : TypedAstNode, optional
         The value if True. If `x` is provided, `y` should also be provided.
 
-    y : PyccelAstNode, optional
+    y : TypedAstNode, optional
         The value if False. If `y` is provided, `x` should also be provided.
     """
 
@@ -1045,7 +1045,7 @@ class NumpyRand(PyccelInternalFunction):
 
     Parameters
     ----------
-    *args : tuple of PyccelAstNode
+    *args : tuple of TypedAstNode
         The arguments passed to the function.
     """
     __slots__ = ('_shape','_rank','_order')
@@ -1112,12 +1112,12 @@ class NumpyFull(NumpyNewArray):
 
     Parameters
     ----------
-    shape : PyccelAstNode
+    shape : TypedAstNode
         Shape of the new array, e.g., ``(2, 3)`` or ``2``.
         For a 1D array this is either a `LiteralInteger` or an expression.
         For a ND array this is a `PythonTuple` or a `HomogeneousTupleVariable`.
 
-    fill_value : PyccelAstNode
+    fill_value : TypedAstNode
         Fill value.
 
     dtype : PythonType, PyccelFunctionDef, LiteralString, str, optional
@@ -1183,7 +1183,7 @@ class NumpyEmpty(NumpyAutoFill):
 
     Parameters
     ----------
-    shape : PyccelAstNode
+    shape : TypedAstNode
         The shape of the array to be created.
 
     dtype : PythonType, PyccelFunctionDef, LiteralString, str
@@ -1260,7 +1260,7 @@ class constructor always returns an object of type `NumpyFull`.
     a : Variable
         Numpy array which is used as a template.
 
-    fill_value : PyccelAstNode
+    fill_value : TypedAstNode
         Scalar value which will be assigned to each entry of the new array.
 
     dtype : PythonType, PyccelFunctionDef, LiteralString, str, optional
@@ -1272,7 +1272,7 @@ class constructor always returns an object of type `NumpyFull`.
     subok : bool, default=True
         This parameter is currently ignored.
 
-    shape : PythonTuple of PyccelAstNode
+    shape : PythonTuple of TypedAstNode
         Overrides the shape of the array.
         For a 1D array this is either a `LiteralInteger` or an expression.
         For a ND array this is a `PythonTuple` or a `HomogeneousTupleVariable`.
@@ -1316,7 +1316,7 @@ class constructor always returns an object of type `NumpyEmpty`.
     subok : bool, default=True
         This parameter is currently ignored.
 
-    shape : PythonTuple of PyccelAstNode
+    shape : PythonTuple of TypedAstNode
         Overrides the shape of the array.
         For a 1D array this is either a `LiteralInteger` or an expression.
         For a ND array this is a `PythonTuple` or a `HomogeneousTupleVariable`.
@@ -1362,7 +1362,7 @@ class constructor always returns an object of type `NumpyOnes`.
     subok : bool, default=True
         This parameter is currently ignored.
 
-    shape : PythonTuple of PyccelAstNode
+    shape : PythonTuple of TypedAstNode
         Overrides the shape of the array.
         For a 1D array this is either a `LiteralInteger` or an expression.
         For a ND array this is a `PythonTuple` or a `HomogeneousTupleVariable`.
@@ -1407,7 +1407,7 @@ class constructor always returns an object of type `NumpyZeros`.
     subok : bool, default=True
         This parameter is currently ignored.
 
-    shape : PythonTuple of PyccelAstNode
+    shape : PythonTuple of TypedAstNode
         Overrides the shape of the array.
         For a 1D array this is either a `LiteralInteger` or an expression.
         For a ND array this is a `PythonTuple` or a `HomogeneousTupleVariable`.
@@ -1500,7 +1500,7 @@ class NumpyUfuncUnary(NumpyUfuncBase):
 
     Parameters
     ----------
-    x : PyccelAstNode
+    x : TypedAstNode
         The argument passed to the function.
     """
     __slots__ = ()
@@ -1522,7 +1522,7 @@ def _set_dtype_precision(self, x):
 
         Parameters
         ----------
-        x : PyccelAstNode
+        x : TypedAstNode
             The argument passed to the function.
         """
         self._dtype      = x.dtype if x.dtype is NativeComplex() else NativeFloat()
@@ -1546,9 +1546,9 @@ class NumpyUfuncBinary(NumpyUfuncBase):
 
     Parameters
     ----------
-    x1 : PyccelAstNode
+    x1 : TypedAstNode
         The first argument passed to the function.
-    x2 : PyccelAstNode
+    x2 : TypedAstNode
         The second argument passed to the function.
     """
     __slots__ = ()
@@ -1570,9 +1570,9 @@ def _set_dtype_precision(self, x1, x2):
 
         Parameters
         ----------
-        x1 : PyccelAstNode
+        x1 : TypedAstNode
             The first argument passed to the function.
-        x2 : PyccelAstNode
+        x2 : TypedAstNode
             The second argument passed to the function.
         """
         self._dtype     = NativeFloat()
@@ -1700,7 +1700,7 @@ class NumpyFloor(NumpyUfuncUnary):
 
     Parameters
     ----------
-    x : PyccelAstNode
+    x : TypedAstNode
         The argument passed to the function.
     """
     __slots__ = ()
@@ -1714,7 +1714,7 @@ def _set_dtype_precision(self, x):
 
         Parameters
         ----------
-        x : PyccelAstNode
+        x : TypedAstNode
             The argument passed to the function.
         """
         self._dtype     = NativeFloat()
@@ -1728,9 +1728,9 @@ class NumpyMod(NumpyUfuncBinary):
 
     Parameters
     ----------
-    x1 : PyccelAstNode
+    x1 : TypedAstNode
         Dividend of the operator.
-    x2 : PyccelAstNode
+    x2 : TypedAstNode
         Divisor of the operator.
     """
     __slots__ = ()
@@ -1771,9 +1771,9 @@ def _set_dtype_precision(self, x1, x2):
 
         Parameters
         ----------
-        x1 : PyccelAstNode
+        x1 : TypedAstNode
             The first argument which helps determine the datatype.
-        x2 : PyccelAstNode
+        x2 : TypedAstNode
             The second argument which helps determine the datatype.
         """
         args      = (x1, x2)
@@ -1897,7 +1897,7 @@ class NumpyNonZeroElement(NumpyNewArray):
 
     Parameters
     ----------
-    a : PyccelAstNode
+    a : TypedAstNode
         The argument which was passed to numpy.nonzero.
     dim : int
         The index of the element in the tuple.
@@ -1938,7 +1938,7 @@ class NumpyNonZero(NumpyNewArray):
 
     Parameters
     ----------
-    a : PyccelAstNode
+    a : TypedAstNode
         The array argument that was passed to the function.
 
     Examples
@@ -1984,7 +1984,7 @@ class NumpyCountNonZero(PyccelInternalFunction):
 
     Parameters
     ==========
-    arg   : PyccelAstNode
+    arg   : TypedAstNode
             An array for which the non-zero elements should be counted
     axis  : int
             The dimension along which the non-zero elements are counted
@@ -2063,10 +2063,10 @@ class constructor returns objects of type `PyccelArraySize`, `LiteralInteger`, o
 
     Parameters
     ----------
-    a : PyccelAstNode
+    a : TypedAstNode
         An array of unknown size.
 
-    axis : PyccelAstNode, optional
+    axis : TypedAstNode, optional
         The integer dimension along which the size is requested.
 
     See Also
diff --git a/pyccel/ast/omp.py b/pyccel/ast/omp.py
index 0c61d9e721..594283e843 100644
--- a/pyccel/ast/omp.py
+++ b/pyccel/ast/omp.py
@@ -10,7 +10,7 @@
 https://github.com/pyccel/pyccel/blob/master/tutorial/openmp.md
 """
 
-from .basic import Basic
+from .basic import PyccelAstNode
 
 __all__ = ('OmpAnnotatedComment',
            'OMP_For_Loop',
@@ -30,7 +30,7 @@
            'OMP_Section_Construct',
            'Omp_End_Clause')
 
-class OmpAnnotatedComment(Basic):
+class OmpAnnotatedComment(PyccelAstNode):
 
     """Represents an OpenMP Annotated Comment in the code.
 
diff --git a/pyccel/ast/operators.py b/pyccel/ast/operators.py
index d863a85d00..b7d3e46b5d 100644
--- a/pyccel/ast/operators.py
+++ b/pyccel/ast/operators.py
@@ -13,7 +13,7 @@
 
 from ..errors.errors        import Errors, PyccelSemanticError
 
-from .basic                 import PyccelAstNode
+from .basic                 import TypedAstNode
 
 from .datatypes             import (NativeBool, NativeInteger, NativeFloat,
                                     NativeComplex, NativeString,
@@ -122,7 +122,7 @@ def broadcast(shape_1, shape_2):
 
 #==============================================================================
 
-class PyccelOperator(PyccelAstNode):
+class PyccelOperator(TypedAstNode):
     """
     Abstract superclass for all builtin operators.
     The __init__ function is common
@@ -230,7 +230,7 @@ class PyccelUnaryOperator(PyccelOperator):
 
     Parameters
     ----------
-    arg: PyccelAstNode
+    arg: TypedAstNode
         The argument passed to the operator
     """
     __slots__ = ('_dtype', '_precision','_shape','_rank','_order')
@@ -267,7 +267,7 @@ class PyccelUnary(PyccelUnaryOperator):
 
     Parameters
     ----------
-    arg: PyccelAstNode
+    arg: TypedAstNode
         The argument passed to the operator
     """
     __slots__ = ()
@@ -292,7 +292,7 @@ class PyccelUnarySub(PyccelUnary):
 
     Parameters
     ----------
-    arg: PyccelAstNode
+    arg: TypedAstNode
         The argument passed to the operator
     """
     __slots__ = ()
@@ -312,7 +312,7 @@ class PyccelNot(PyccelUnaryOperator):
 
     Parameters
     ----------
-    arg: PyccelAstNode
+    arg: TypedAstNode
         The argument passed to the operator
     """
     __slots__ = ()
@@ -349,7 +349,7 @@ class PyccelAssociativeParenthesis(PyccelUnaryOperator):
 
     Parameters
     ----------
-    arg: PyccelAstNode
+    arg: TypedAstNode
         The argument in the PyccelAssociativeParenthesis
     """
     __slots__ = () # ok
@@ -368,9 +368,9 @@ class PyccelBinaryOperator(PyccelOperator):
 
     Parameters
     ----------
-    arg1: PyccelAstNode
+    arg1: TypedAstNode
         The first argument passed to the operator
-    arg2: PyccelAstNode
+    arg2: TypedAstNode
         The second argument passed to the operator
     """
     __slots__ = ('_dtype','_precision','_shape','_rank','_order')
@@ -475,9 +475,9 @@ class PyccelArithmeticOperator(PyccelBinaryOperator):
 
     Parameters
     ----------
-    arg1: PyccelAstNode
+    arg1: TypedAstNode
         The first argument passed to the operator
-    arg2: PyccelAstNode
+    arg2: TypedAstNode
         The second argument passed to the operator
     """
     __slots__ = ()
@@ -498,9 +498,9 @@ class PyccelPow(PyccelArithmeticOperator):
 
     Parameters
     ----------
-    arg1: PyccelAstNode
+    arg1: TypedAstNode
         The first argument passed to the operator
-    arg2: PyccelAstNode
+    arg2: TypedAstNode
         The second argument passed to the operator
     """
     __slots__ = ()
@@ -537,9 +537,9 @@ class PyccelAdd(PyccelArithmeticOperator):
 
     Parameters
     ----------
-    arg1: PyccelAstNode
+    arg1: TypedAstNode
         The first argument passed to the operator
-    arg2: PyccelAstNode
+    arg2: TypedAstNode
         The second argument passed to the operator
     """
     __slots__ = ()
@@ -592,9 +592,9 @@ class PyccelMul(PyccelArithmeticOperator):
 
     Parameters
     ----------
-    arg1: PyccelAstNode
+    arg1: TypedAstNode
         The first argument passed to the operator
-    arg2: PyccelAstNode
+    arg2: TypedAstNode
         The second argument passed to the operator
     """
     __slots__ = ()
@@ -634,9 +634,9 @@ class PyccelMinus(PyccelArithmeticOperator):
 
     Parameters
     ----------
-    arg1: PyccelAstNode
+    arg1: TypedAstNode
         The first argument passed to the operator
-    arg2: PyccelAstNode
+    arg2: TypedAstNode
         The second argument passed to the operator
     """
     __slots__ = ()
@@ -676,9 +676,9 @@ class PyccelDiv(PyccelArithmeticOperator):
 
     Parameters
     ----------
-    arg1: PyccelAstNode
+    arg1: TypedAstNode
         The first argument passed to the operator
-    arg2: PyccelAstNode
+    arg2: TypedAstNode
         The second argument passed to the operator
     """
     __slots__ = ()
@@ -711,9 +711,9 @@ class PyccelMod(PyccelArithmeticOperator):
 
     Parameters
     ----------
-    arg1: PyccelAstNode
+    arg1: TypedAstNode
         The first argument passed to the operator
-    arg2: PyccelAstNode
+    arg2: TypedAstNode
         The second argument passed to the operator
     """
     __slots__ = ()
@@ -734,9 +734,9 @@ class PyccelFloorDiv(PyccelArithmeticOperator):
 
     Parameters
     ----------
-    arg1: PyccelAstNode
+    arg1: TypedAstNode
         The first argument passed to the operator
-    arg2: PyccelAstNode
+    arg2: TypedAstNode
         The second argument passed to the operator
     """
     __slots__ = ()
@@ -753,9 +753,9 @@ class PyccelComparisonOperator(PyccelBinaryOperator):
 
     Parameters
     ----------
-    arg1: PyccelAstNode
+    arg1: TypedAstNode
         The first argument passed to the operator
-    arg2: PyccelAstNode
+    arg2: TypedAstNode
         The second argument passed to the operator
     """
     __slots__ = ()
@@ -778,9 +778,9 @@ class PyccelEq(PyccelComparisonOperator):
 
     Parameters
     ----------
-    arg1: PyccelAstNode
+    arg1: TypedAstNode
         The first argument passed to the operator
-    arg2: PyccelAstNode
+    arg2: TypedAstNode
         The second argument passed to the operator
     """
     __slots__ = ()
@@ -804,9 +804,9 @@ class PyccelNe(PyccelComparisonOperator):
 
     Parameters
     ----------
-    arg1: PyccelAstNode
+    arg1: TypedAstNode
         The first argument passed to the operator
-    arg2: PyccelAstNode
+    arg2: TypedAstNode
         The second argument passed to the operator
     """
     __slots__ = ()
@@ -830,9 +830,9 @@ class PyccelLt(PyccelComparisonOperator):
 
     Parameters
     ----------
-    arg1: PyccelAstNode
+    arg1: TypedAstNode
         The first argument passed to the operator
-    arg2: PyccelAstNode
+    arg2: TypedAstNode
         The second argument passed to the operator
     """
     __slots__ = ()
@@ -850,9 +850,9 @@ class PyccelLe(PyccelComparisonOperator):
 
     Parameters
     ----------
-    arg1: PyccelAstNode
+    arg1: TypedAstNode
         The first argument passed to the operator
-    arg2: PyccelAstNode
+    arg2: TypedAstNode
         The second argument passed to the operator
     """
     __slots__ = ()
@@ -870,9 +870,9 @@ class PyccelGt(PyccelComparisonOperator):
 
     Parameters
     ----------
-    arg1: PyccelAstNode
+    arg1: TypedAstNode
         The first argument passed to the operator
-    arg2: PyccelAstNode
+    arg2: TypedAstNode
         The second argument passed to the operator
     """
     __slots__ = ()
@@ -890,9 +890,9 @@ class PyccelGe(PyccelComparisonOperator):
 
     Parameters
     ----------
-    arg1: PyccelAstNode
+    arg1: TypedAstNode
         The first argument passed to the operator
-    arg2: PyccelAstNode
+    arg2: TypedAstNode
         The second argument passed to the operator
     """
     __slots__ = ()
@@ -908,9 +908,9 @@ class PyccelBooleanOperator(PyccelOperator):
 
     Parameters
     ----------
-    arg1: PyccelAstNode
+    arg1: TypedAstNode
         The first argument passed to the operator
-    arg2: PyccelAstNode
+    arg2: TypedAstNode
         The second argument passed to the operator
     """
     dtype = NativeBool()
@@ -942,9 +942,9 @@ class PyccelAnd(PyccelBooleanOperator):
 
     Parameters
     ----------
-    arg1: PyccelAstNode
+    arg1: TypedAstNode
         The first argument passed to the operator
-    arg2: PyccelAstNode
+    arg2: TypedAstNode
         The second argument passed to the operator
     """
     __slots__ = ()
@@ -969,9 +969,9 @@ class PyccelOr(PyccelBooleanOperator):
 
     Parameters
     ----------
-    arg1: PyccelAstNode
+    arg1: TypedAstNode
         The first argument passed to the operator
-    arg2: PyccelAstNode
+    arg2: TypedAstNode
         The second argument passed to the operator
     """
     __slots__ = ()
diff --git a/pyccel/ast/sympy_helper.py b/pyccel/ast/sympy_helper.py
index 01d35b038c..dd838cfdb7 100644
--- a/pyccel/ast/sympy_helper.py
+++ b/pyccel/ast/sympy_helper.py
@@ -44,7 +44,7 @@ def sympy_to_pyccel(expr, symbol_map):
 
     Returns
     -------
-    PyccelAstNode
+    TypedAstNode
         The Pyccel equivalent of the SymPy object `expr`.
     """
 
@@ -122,7 +122,7 @@ def pyccel_to_sympy(expr, symbol_map, used_names):
 
     Parameters
     ----------
-    expr : PyccelAstNode
+    expr : TypedAstNode
         The Pyccel node to be translated.
 
     symbol_map : dict
diff --git a/pyccel/ast/sysext.py b/pyccel/ast/sysext.py
index 355ce16152..58c0f1654f 100644
--- a/pyccel/ast/sysext.py
+++ b/pyccel/ast/sysext.py
@@ -23,7 +23,7 @@ class SysExit(PyccelInternalFunction):
     Parameters
     ----------
 
-    arg : PyccelAstNode (optional)
+    arg : TypedAstNode (optional)
         if arg.dtype is NativeInteger it will be used as the exit_code
         else the arg will be printed to the stderror
     """
diff --git a/pyccel/ast/type_annotations.py b/pyccel/ast/type_annotations.py
index c3271495bb..b99a5abbbd 100644
--- a/pyccel/ast/type_annotations.py
+++ b/pyccel/ast/type_annotations.py
@@ -7,7 +7,7 @@
 """ Module containing all classes useful for type annotation.
 """
 
-from .basic import Basic
+from .basic import PyccelAstNode
 
 __all__ = (
         'SyntacticTypeAnnotation',
@@ -15,7 +15,7 @@
         'UnionTypeAnnotation',
         )
 
-class VariableTypeAnnotation(Basic):
+class VariableTypeAnnotation(PyccelAstNode):
     """
     A class which describes a type annotation.
 
@@ -122,7 +122,7 @@ def __hash__(self):
     def __repr__(self):
         return f"{self._datatype}{self._precision}[{self._rank}]({self._order})"
 
-class UnionTypeAnnotation(Basic):
+class UnionTypeAnnotation(PyccelAstNode):
     """
     A class which holds multiple possible type annotations.
 
@@ -151,7 +151,7 @@ def type_list(self):
         """
         return self._type_annotations
 
-class SyntacticTypeAnnotation(Basic):
+class SyntacticTypeAnnotation(PyccelAstNode):
     """
     A class describing the type annotation parsed in the syntactic stage.
 
diff --git a/pyccel/ast/utilities.py b/pyccel/ast/utilities.py
index 68d95e550d..33e6b1ba95 100644
--- a/pyccel/ast/utilities.py
+++ b/pyccel/ast/utilities.py
@@ -232,7 +232,7 @@ def compatible_operation(*args, language_has_vectors = True):
 
     Parameters
     ==========
-    args      : list of PyccelAstNode
+    args      : list of TypedAstNode
                 The operator arguments
     language_has_vectors : bool
                 Indicates if the language has support for vector
@@ -635,7 +635,7 @@ def insert_fors(blocks, indices, scope, level = 0):
             The index of the index variable used in the outermost loop
     Results
     =======
-    block : list of PyccelAstNodes
+    block : list of TypedAstNodes
             The modified expression
     """
     if all(not isinstance(b, LoopCollection) for b in blocks.body):
diff --git a/pyccel/ast/variable.py b/pyccel/ast/variable.py
index 09ac50f2b4..7602fb3778 100644
--- a/pyccel/ast/variable.py
+++ b/pyccel/ast/variable.py
@@ -12,7 +12,7 @@
 from pyccel.errors.errors   import Errors
 from pyccel.utilities.stage import PyccelStage
 
-from .basic     import Basic, PyccelAstNode
+from .basic     import PyccelAstNode, TypedAstNode
 from .datatypes import (datatype, DataType,
                         NativeInteger, NativeBool, NativeFloat,
                         NativeComplex)
@@ -35,7 +35,7 @@
     'Variable'
 )
 
-class Variable(PyccelAstNode):
+class Variable(TypedAstNode):
     """
     Represents a typed variable.
 
@@ -74,7 +74,7 @@ class Variable(PyccelAstNode):
 
     shape : tuple, default: None
         The shape of the array. A tuple whose elements indicate the number of elements along
-        each of the dimensions of an array. The elements of the tuple should be None or PyccelAstNodes.
+        each of the dimensions of an array. The elements of the tuple should be None or TypedAstNodes.
 
     cls_base : class, default: None
         Class base if variable is an object or an object member.
@@ -180,7 +180,7 @@ def __init__(
         self._is_argument    = is_argument
         self._is_temp        = is_temp
 
-        # ------------ PyccelAstNode Properties ---------------
+        # ------------ TypedAstNode Properties ---------------
         if isinstance(dtype, str) or str(dtype) == '*':
 
             dtype = datatype(dtype)
@@ -252,11 +252,11 @@ def process_shape(self, shape):
                 new_shape.append(s)
             elif isinstance(s, int):
                 new_shape.append(LiteralInteger(s))
-            elif s is None or isinstance(s, PyccelAstNode):
+            elif s is None or isinstance(s, TypedAstNode):
                 new_shape.append(PyccelArrayShapeElement(self, LiteralInteger(i)))
             else:
                 raise TypeError('shape elements cannot be '+str(type(s))+'. They must be one of the following types: LiteralInteger,'
-                                'Variable, Slice, PyccelAstNode, int, Function')
+                                'Variable, Slice, TypedAstNode, int, Function')
         return tuple(new_shape)
 
     def shape_can_change(self, i):
@@ -299,7 +299,7 @@ def set_init_shape(self, shape):
         ----------
         shape : tuple
             The shape of the array. A tuple whose elements indicate the number of elements along
-            each of the dimensions of an array. The elements of the tuple should be None or PyccelAstNodes.
+            each of the dimensions of an array. The elements of the tuple should be None or TypedAstNodes.
         """
         self._alloc_shape = shape
         self._shape = self.process_shape(shape)
@@ -588,7 +588,7 @@ def is_temp(self, is_temp):
             raise ValueError("Variables cannot become temporary")
         self._is_temp = is_temp
 
-class DottedName(Basic):
+class DottedName(PyccelAstNode):
 
     """
     Represents a dotted object.
@@ -834,7 +834,7 @@ def __str__(self):
 
 
 
-class IndexedElement(PyccelAstNode):
+class IndexedElement(TypedAstNode):
 
     """
     Represents a mathematical object with indices.
@@ -880,7 +880,7 @@ def __init__(
         if len(args) < rank:
             args = args + tuple([Slice(None, None)]*(rank-len(args)))
 
-        if any(not isinstance(a, (int, PyccelAstNode, Slice)) for a in args):
+        if any(not isinstance(a, (int, TypedAstNode, Slice)) for a in args):
             errors.report("Index is not of valid type",
                     symbol = args, severity = 'fatal')
 
diff --git a/pyccel/codegen/printing/ccode.py b/pyccel/codegen/printing/ccode.py
index 9ed052689f..60d9907d0e 100644
--- a/pyccel/codegen/printing/ccode.py
+++ b/pyccel/codegen/printing/ccode.py
@@ -7,7 +7,7 @@
 from itertools import chain
 import re
 
-from pyccel.ast.basic     import ScopedNode
+from pyccel.ast.basic     import ScopedAstNode
 
 from pyccel.ast.builtins  import PythonRange, PythonComplex
 from pyccel.ast.builtins  import PythonPrint, PythonType
@@ -349,7 +349,7 @@ def is_c_pointer(self, a):
 
         Parameters
         ----------
-        a : PyccelAstNode
+        a : TypedAstNode
             The object whose storage we are enquiring about.
 
         Returns
@@ -381,7 +381,7 @@ def copy_NumpyArray_Data(self, expr):
 
         Parameters
         ----------
-        expr : PyccelAstNode
+        expr : TypedAstNode
             The Assign Node used to get the lhs and rhs.
 
         Returns
@@ -474,7 +474,7 @@ def arrayFill(self, expr):
 
         Parameters
         ----------
-        expr : PyccelAstNode
+        expr : TypedAstNode
             The Assign Node used to get the lhs and rhs.
 
         Returns
@@ -502,7 +502,7 @@ def _init_stack_array(self, expr):
 
         Parameters
         ----------
-        expr : PyccelAstNode
+        expr : TypedAstNode
             The Assign Node used to get the lhs and rhs.
 
         Returns
@@ -557,7 +557,7 @@ def _handle_inline_func_call(self, expr):
         body = func.body
 
         for b in body.body:
-            if isinstance(b, ScopedNode):
+            if isinstance(b, ScopedAstNode):
                 b.scope.update_parent_scope(self.scope, is_loop=True)
 
         # Print any arguments using the same inline function
@@ -623,7 +623,7 @@ def _handle_inline_func_call(self, expr):
                 self.scope.insert_symbol(v.name)
 
         for b in body.body:
-            if isinstance(b, ScopedNode):
+            if isinstance(b, ScopedAstNode):
                 b.scope.update_parent_scope(func.scope, is_loop=True)
 
         return code
@@ -971,7 +971,7 @@ def get_print_format_and_arg(self, var):
 
         Parameters
         ----------
-        var : PyccelAstNode
+        var : TypedAstNode
             The object which will be printed.
 
         Returns
@@ -1376,7 +1376,7 @@ def _cast_to(self, expr, dtype, precision):
 
         Parameters
         ----------
-        expr : PyccelAstNode
+        expr : TypedAstNode
             The expression to be cast.
         dtype : Datatype
             The target type of the cast.
diff --git a/pyccel/codegen/printing/codeprinter.py b/pyccel/codegen/printing/codeprinter.py
index f0e71a0af7..dcc97359b6 100644
--- a/pyccel/codegen/printing/codeprinter.py
+++ b/pyccel/codegen/printing/codeprinter.py
@@ -5,7 +5,7 @@
 #------------------------------------------------------------------------------------------#
 
 
-from pyccel.ast.basic import Basic
+from pyccel.ast.basic import PyccelAstNode
 
 from pyccel.ast.core      import Assign
 from pyccel.ast.internals import PyccelSymbol
@@ -41,7 +41,7 @@ def doprint(self, expr, assign_to=None):
 
         if isinstance(assign_to, str):
             assign_to = PyccelSymbol(assign_to)
-        elif not isinstance(assign_to, (Basic, type(None))):
+        elif not isinstance(assign_to, (PyccelAstNode, type(None))):
             raise TypeError("{0} cannot assign to object of type {1}".format(
                     type(self).__name__, type(assign_to)))
 
diff --git a/pyccel/codegen/printing/cwrappercode.py b/pyccel/codegen/printing/cwrappercode.py
index 04cfaa1037..8af12a3618 100644
--- a/pyccel/codegen/printing/cwrappercode.py
+++ b/pyccel/codegen/printing/cwrappercode.py
@@ -72,7 +72,7 @@ def is_c_pointer(self, a):
 
         Parameters
         ----------
-        a : PyccelAstNode
+        a : TypedAstNode
             The object whose storage we are enquiring about.
 
         Returns
@@ -104,7 +104,7 @@ def get_python_name(self, scope, obj):
         scope : pyccel.parser.scope.Scope
             The scope where the object was defined.
 
-        obj : pyccel.ast.basic.Basic
+        obj : pyccel.ast.basic.PyccelAstNode
             The object whose name we wish to identify.
 
         Returns
diff --git a/pyccel/codegen/printing/fcode.py b/pyccel/codegen/printing/fcode.py
index ce318dc745..cee10ffa9a 100644
--- a/pyccel/codegen/printing/fcode.py
+++ b/pyccel/codegen/printing/fcode.py
@@ -14,7 +14,7 @@
 
 import functools
 
-from pyccel.ast.basic import PyccelAstNode
+from pyccel.ast.basic import TypedAstNode
 
 from pyccel.ast.bind_c import BindCPointer, BindCFunctionDef, BindCFunctionDefArgument, BindCModule
 
@@ -691,9 +691,9 @@ def _formatted_args_to_print(self, fargs_format, fargs, fend, fsep, expr):
                        The format strings for the objects described by fargs
         fargs        : iterable
                        The args to be printed
-        fend         : PyccelAstNode
+        fend         : TypedAstNode
                        The character describing the end of the line
-        expr         : PyccelAstNode
+        expr         : TypedAstNode
                         The PythonPrint currently printed
         """
         if fargs_format == ['*']:
@@ -732,7 +732,7 @@ def _get_print_format_and_arg(self,var):
 
         Parameters
         ----------
-        var : PyccelAstNode
+        var : TypedAstNode
               The object to be printed
 
         Results
@@ -1450,7 +1450,7 @@ def _print_Declare(self, expr):
 
         # Compute rank string
         # TODO: improve
-        if ((rank == 1) and (isinstance(shape, (int, PyccelAstNode))) and (is_static or on_stack)):
+        if ((rank == 1) and (isinstance(shape, (int, TypedAstNode))) and (is_static or on_stack)):
             rankstr = '({0}:{1})'.format(self._print(s), self._print(PyccelMinus(shape, LiteralInteger(1), simplify = True)))
 
         elif ((rank > 0) and (isinstance(shape, (PythonTuple, tuple))) and (is_static or on_stack)):
diff --git a/pyccel/codegen/printing/pycode.py b/pyccel/codegen/printing/pycode.py
index 4da120d97c..1164b81e17 100644
--- a/pyccel/codegen/printing/pycode.py
+++ b/pyccel/codegen/printing/pycode.py
@@ -120,7 +120,7 @@ def _find_functional_expr_and_iterables(self, expr):
 
         Returns
         -------
-        body      : PyccelAstNode
+        body      : TypedAstNode
                     The expression inside the for loops
         iterables : list of Iterables
                     The iterables over which the for loops iterate
@@ -194,7 +194,7 @@ def _print_dtype_argument(self, expr, init_dtype):
 
         Parameters
         ----------
-        expr : PyccelAstNode
+        expr : TypedAstNode
             The expression whose datatype is being determined.
 
         init_dtype : PythonType, PyccelFunctionDef, LiteralString, str
diff --git a/pyccel/codegen/wrapper/c_to_python_wrapper.py b/pyccel/codegen/wrapper/c_to_python_wrapper.py
index 4a13dc5f7e..370eca91a2 100644
--- a/pyccel/codegen/wrapper/c_to_python_wrapper.py
+++ b/pyccel/codegen/wrapper/c_to_python_wrapper.py
@@ -128,7 +128,7 @@ def _unpack_python_args(self, args):
         func_args : list of Variable
             The arguments of the FunctionDef.
 
-        body : list of pyccel.ast.basic.Basic
+        body : list of pyccel.ast.basic.PyccelAstNode
             The code which unpacks the arguments.
 
         Examples
@@ -217,7 +217,7 @@ def _get_check_function(self, py_obj, arg, raise_error):
         func_call : FunctionCall
             The function call which checks if the argument has the expected type.
 
-        error_code : tuple of pyccel.ast.basic.Basic
+        error_code : tuple of pyccel.ast.basic.PyccelAstNode
             The code which raises any necessary errors.
         """
         rank = arg.rank
@@ -805,7 +805,7 @@ def _wrap_FunctionDefArgument(self, expr):
 
         Returns
         -------
-        list of pyccel.ast.basic.Basic
+        list of pyccel.ast.basic.PyccelAstNode
             The code which translates the `PyccelPyObject` to a C-compatible variable.
         """
 
@@ -883,7 +883,7 @@ def _wrap_BindCFunctionDefArgument(self, expr):
 
         Returns
         -------
-        list of pyccel.ast.basic.Basic
+        list of pyccel.ast.basic.PyccelAstNode
             The code which translates the `PyccelPyObject` to a C-compatible variable.
         """
         body = self._wrap_FunctionDefArgument(expr)
@@ -938,7 +938,7 @@ def _wrap_FunctionDefResult(self, expr):
 
         Returns
         -------
-        list of pyccel.ast.basic.Basic
+        list of pyccel.ast.basic.PyccelAstNode
             The code which translates the variable to a `PyccelPyObject`.
         """
 
@@ -988,7 +988,7 @@ def _wrap_BindCFunctionDefResult(self, expr):
 
         Returns
         -------
-        list of pyccel.ast.basic.Basic
+        list of pyccel.ast.basic.PyccelAstNode
             The code which translates the variable to a `PyccelPyObject`.
         """
 
@@ -1039,7 +1039,7 @@ def _wrap_Variable(self, expr):
 
         Returns
         -------
-        list of pyccel.ast.basic.Basic
+        list of pyccel.ast.basic.PyccelAstNode
             The code which translates the Variable to a Python-compatible variable.
         """
 
@@ -1079,7 +1079,7 @@ def _wrap_BindCArrayVariable(self, expr):
 
         Returns
         -------
-        list of pyccel.ast.basic.Basic
+        list of pyccel.ast.basic.PyccelAstNode
             The code which translates the Variable to a Python-compatible variable.
         """
         v = expr.original_variable
diff --git a/pyccel/codegen/wrapper/fortran_to_c_wrapper.py b/pyccel/codegen/wrapper/fortran_to_c_wrapper.py
index 0efa1dfdd4..08bfde08c4 100644
--- a/pyccel/codegen/wrapper/fortran_to_c_wrapper.py
+++ b/pyccel/codegen/wrapper/fortran_to_c_wrapper.py
@@ -127,7 +127,7 @@ def _get_call_argument(self, bind_c_arg):
 
         Returns
         -------
-        PyccelAstNode
+        TypedAstNode
             An object which can be passed to a function call of the function
             being wrapped.
         """
@@ -417,7 +417,7 @@ def _wrap_Variable(self, expr):
 
         Returns
         -------
-        pyccel.ast.basic.Basic
+        pyccel.ast.basic.PyccelAstNode
             The AST object describing the code which must be printed in
             the wrapping module to expose the variable.
         """
diff --git a/pyccel/codegen/wrapper/wrapper.py b/pyccel/codegen/wrapper/wrapper.py
index a260e2b12b..e4b4220455 100644
--- a/pyccel/codegen/wrapper/wrapper.py
+++ b/pyccel/codegen/wrapper/wrapper.py
@@ -67,12 +67,12 @@ def wrap(self, expr):
 
         Parameters
         ----------
-        expr : pyccel.ast.basic.Basic
+        expr : pyccel.ast.basic.PyccelAstNode
             The expression that should be wrapped.
 
         Returns
         -------
-        pyccel.ast.basic.Basic
+        pyccel.ast.basic.PyccelAstNode
             The AST which describes the object that lets you
             access the expression.
         """
@@ -87,12 +87,12 @@ def _wrap(self, expr):
 
         Parameters
         ----------
-        expr : pyccel.ast.basic.Basic
+        expr : pyccel.ast.basic.PyccelAstNode
             The expression that should be wrapped.
 
         Returns
         -------
-        pyccel.ast.basic.Basic
+        pyccel.ast.basic.PyccelAstNode
             The AST which describes the object that lets you
             access the expression.
         """
diff --git a/pyccel/complexity/memory.py b/pyccel/complexity/memory.py
index 2f74bc58c8..5bf110c8aa 100644
--- a/pyccel/complexity/memory.py
+++ b/pyccel/complexity/memory.py
@@ -35,7 +35,7 @@
 from sympy import sympify, Symbol
 from sympy import Poly, LT
 
-from pyccel.ast.basic        import Basic
+from pyccel.ast.basic        import PyccelAstNode
 from pyccel.ast.builtins     import PythonTuple
 from pyccel.ast.core         import For, Assign, CodeBlock, FunctionDef
 from pyccel.ast.core         import Module, Program
@@ -93,7 +93,7 @@ def count_access(expr, visual=True):
         import numpy as np
         return WRITE*np.prod(expr.shape)
 
-    elif isinstance(expr, Basic):
+    elif isinstance(expr, PyccelAstNode):
 
         atoms = expr.get_attribute_nodes(PyccelSymbol, FunctionDef)
         return READ*len(atoms)
diff --git a/pyccel/errors/errors.py b/pyccel/errors/errors.py
index 85b1d6e761..eaf1d644a1 100644
--- a/pyccel/errors/errors.py
+++ b/pyccel/errors/errors.py
@@ -14,7 +14,7 @@
 from collections import OrderedDict
 from os.path import basename
 
-from pyccel.ast.basic import Basic
+from pyccel.ast.basic import PyccelAstNode
 from pyccel.utilities.metaclasses import Singleton
 
 # ...
@@ -103,8 +103,8 @@ class ErrorInfo:
     severity : str, optional
         The severity of the error. This is one of : [warning/error/fatal].
 
-    symbol : pyccel.ast.basic.Basic, optional
-        The Basic object which caused the error to need to be raised.
+    symbol : pyccel.ast.basic.PyccelAstNode, optional
+        The PyccelAstNode object which caused the error to need to be raised.
         This object is printed in the error message.
 
     traceback : str, optional
@@ -281,8 +281,8 @@ def report(self,
             Indicates the seriousness of the error. Should be one of: 'warning', 'error', 'fatal'.
             Default: 'error'.
 
-        symbol : pyccel.ast.Basic, optional
-            The Basic object which caused the error to need to be raised.
+        symbol : pyccel.ast.PyccelAstNode, optional
+            The PyccelAstNode object which caused the error to need to be raised.
             This object is printed in the error message.
 
         filename : str, optional
@@ -315,7 +315,7 @@ def report(self,
                     symbol = ast.dump(fst)
                 else:
                     symbol = ast.unparse(fst) # pylint: disable=no-member
-            elif isinstance(symbol, Basic):
+            elif isinstance(symbol, PyccelAstNode):
                 fst = symbol.fst
 
         if fst:
diff --git a/pyccel/parser/scope.py b/pyccel/parser/scope.py
index cbd66fffc4..0630c064bb 100644
--- a/pyccel/parser/scope.py
+++ b/pyccel/parser/scope.py
@@ -220,7 +220,7 @@ def find(self, name, category = None, local_only = False):
 
         Returns
         -------
-        pyccel.ast.basic.Basic
+        pyccel.ast.basic.PyccelAstNode
             The object stored in the scope.
         """
         for l in ([category] if category else self._locals.keys()):
diff --git a/pyccel/parser/semantic.py b/pyccel/parser/semantic.py
index 0a1530b125..47d6de4b8b 100644
--- a/pyccel/parser/semantic.py
+++ b/pyccel/parser/semantic.py
@@ -20,7 +20,7 @@
 
 #==============================================================================
 
-from pyccel.ast.basic import Basic, PyccelAstNode, ScopedNode
+from pyccel.ast.basic import PyccelAstNode, TypedAstNode, ScopedAstNode
 
 from pyccel.ast.builtins import PythonPrint
 from pyccel.ast.builtins import PythonInt, PythonBool, PythonFloat, PythonComplex
@@ -285,7 +285,7 @@ def annotate(self):
 
         Returns
         -------
-        pyccel.ast.basic.Basic
+        pyccel.ast.basic.PyccelAstNode
             An annotated object which can be printed.
         """
 
@@ -531,7 +531,7 @@ def _infer_type(self, expr):
 
         Parameters
         ----------
-        expr : pyccel.ast.basic.Basic
+        expr : pyccel.ast.basic.PyccelAstNode
                 An AST object representing an object in the code whose type
                 must be determined.
 
@@ -632,7 +632,7 @@ def _infer_type(self, expr):
             d_var['precision'     ] = var.precision
             return d_var
 
-        elif isinstance(expr, PyccelAstNode):
+        elif isinstance(expr, TypedAstNode):
 
             d_var['datatype'   ] = expr.dtype
             d_var['memory_handling'] = 'heap' if expr.rank > 0 else 'stack'
@@ -863,7 +863,7 @@ def _check_argument_compatibility(self, input_args, func_args, expr, elemental):
                      The arguments provided to the function
         func_args  : list
                      The arguments expected by the function
-        expr       : PyccelAstNode
+        expr       : TypedAstNode
                      The expression where this call is found (used for error output)
         elemental  : bool
                      Indicates if the function is elemental
@@ -910,7 +910,7 @@ def _handle_function(self, expr, func, args, is_method = False):
 
         Parameters
         ----------
-        expr : PyccelAstNode
+        expr : TypedAstNode
                The expression where this call is found (used for error output).
 
         func : FunctionDef instance, Interface instance or PyccelInternalFunction type
@@ -948,7 +948,7 @@ def _handle_function(self, expr, func, args, is_method = False):
             return new_expr
         else:
             if self._current_function == func.name:
-                if len(func.results)>0 and not isinstance(func.results[0].var, PyccelAstNode):
+                if len(func.results)>0 and not isinstance(func.results[0].var, TypedAstNode):
                     errors.report(RECURSIVE_RESULTS_REQUIRED, symbol=func, severity="fatal")
 
             parent_assign = expr.get_direct_user_nodes(lambda x: isinstance(x, Assign) and not isinstance(x, AugAssign))
@@ -1318,7 +1318,7 @@ def _ensure_inferred_type_matches_existing(self, dtype, d_var, var, is_augassign
             A boolean indicating if the assign statement is an augassign (tests are less strict).
         new_expressions : list
             A list to which any new expressions created are appended.
-        rhs : PyccelAstNode
+        rhs : TypedAstNode
             The right hand side of the expression : lhs=rhs.
             If is_augassign is False, this value is not used.
         """
@@ -1647,12 +1647,12 @@ def _visit(self, expr):
         
         Parameters
         ----------
-        expr : pyccel.ast.basic.Basic
+        expr : pyccel.ast.basic.PyccelAstNode
             Object to visit of type X.
         
         Returns
         -------
-        pyccel.ast.basic.Basic
+        pyccel.ast.basic.PyccelAstNode
             AST object which is the semantic equivalent of expr.
         """
 
@@ -1669,7 +1669,7 @@ def _visit(self, expr):
             annotation_method = '_visit_' + cls.__name__
             if hasattr(self, annotation_method):
                 obj = getattr(self, annotation_method)(expr)
-                if isinstance(obj, Basic) and self._current_fst_node:
+                if isinstance(obj, PyccelAstNode) and self._current_fst_node:
                     obj.set_fst(self._current_fst_node)
                 self._current_fst_node = current_fst
                 return obj
@@ -1726,11 +1726,11 @@ def _visit_Module(self, expr):
             # Ensure that the function is correctly defined within the namespaces
             init_scope = self.create_new_function_scope(init_func_name)
             for b in init_func_body:
-                if isinstance(b, ScopedNode):
+                if isinstance(b, ScopedAstNode):
                     b.scope.update_parent_scope(init_scope, is_loop = True)
                 if isinstance(b, FunctionalFor):
                     for l in b.loops:
-                        if isinstance(l, ScopedNode):
+                        if isinstance(l, ScopedAstNode):
                             l.scope.update_parent_scope(init_scope, is_loop = True)
 
             self.exit_function_scope()
diff --git a/pyccel/parser/syntactic.py b/pyccel/parser/syntactic.py
index 20b5402f64..94dd3519c7 100644
--- a/pyccel/parser/syntactic.py
+++ b/pyccel/parser/syntactic.py
@@ -18,7 +18,7 @@
 
 #==============================================================================
 
-from pyccel.ast.basic import Basic
+from pyccel.ast.basic import PyccelAstNode
 
 from pyccel.ast.core import FunctionCall, FunctionCallArgument
 from pyccel.ast.core import Module
@@ -160,7 +160,7 @@ def parse(self):
 
         Returns
         -------
-        pyccel.ast.basic.Basic
+        pyccel.ast.basic.PyccelAstNode
             The Pyccel AST object.
         """
 
@@ -200,7 +200,7 @@ def _treat_comment_line(self, line, stmt):
 
         Returns
         -------
-        pyccel.ast.basic.Basic
+        pyccel.ast.basic.PyccelAstNode
             The treated object as a Pyccel ast node.
         """
         if line.startswith('#$'):
@@ -263,7 +263,7 @@ def _visit(self, stmt):
         if hasattr(self, syntax_method):
             self._context.append(stmt)
             result = getattr(self, syntax_method)(stmt)
-            if isinstance(result, Basic) and result.fst is None and isinstance(stmt, ast.AST):
+            if isinstance(result, PyccelAstNode) and result.fst is None and isinstance(stmt, ast.AST):
                 result.set_fst(stmt)
             self._context.pop()
             return result


Test patch:
diff --git a/tests/ast/test_basic.py b/tests/ast/test_basic.py
index 3c46268c36..5002997a3d 100644
--- a/tests/ast/test_basic.py
+++ b/tests/ast/test_basic.py
@@ -4,7 +4,7 @@
 from pyccel.parser.parser   import Parser
 from pyccel.errors.errors   import Errors
 
-from pyccel.ast.basic       import Basic
+from pyccel.ast.basic       import PyccelAstNode
 from pyccel.ast.core        import Assign, Return, FunctionDef, AugAssign, FunctionDefArgument
 from pyccel.ast.literals    import LiteralInteger
 from pyccel.ast.operators   import PyccelOperator, PyccelAdd, PyccelMinus, PyccelMul
@@ -141,16 +141,16 @@ def test_substitute():
     atts = [v for v in atts  if v == interesting_var]
 
     a_var = atts[0]
-    old_parents = a_var.get_user_nodes(Basic)
-    assert len(a_var.get_user_nodes(Basic))>0
+    old_parents = a_var.get_user_nodes(PyccelAstNode)
+    assert len(a_var.get_user_nodes(PyccelAstNode))>0
 
     fst.substitute(a_var, new_var)
 
-    assert len(a_var.get_user_nodes(Basic))==0
+    assert len(a_var.get_user_nodes(PyccelAstNode))==0
 
     atts = set(fst.get_attribute_nodes(Variable))
     assert new_var in atts
-    assert set(new_var.get_user_nodes(Basic)) == set(old_parents)
+    assert set(new_var.get_user_nodes(PyccelAstNode)) == set(old_parents)
 
 def test_substitute_exclude():
     filename = os.path.join(path_dir, "math.py")
@@ -163,17 +163,17 @@ def test_substitute_exclude():
     atts = [v for v in atts  if v == interesting_var]
 
     a_var = atts[0]
-    old_parents = set(a_var.get_user_nodes(Basic))
-    assert len(a_var.get_user_nodes(Basic))>0
+    old_parents = set(a_var.get_user_nodes(PyccelAstNode))
+    assert len(a_var.get_user_nodes(PyccelAstNode))>0
 
     fst.substitute(a_var, new_var, excluded_nodes=(PyccelMinus))
 
-    assert len(a_var.get_user_nodes(Basic))==1
+    assert len(a_var.get_user_nodes(PyccelAstNode))==1
 
     atts = set(fst.get_attribute_nodes(Variable))
     assert new_var in atts
 
-    new_parents = set(new_var.get_user_nodes(Basic))
+    new_parents = set(new_var.get_user_nodes(PyccelAstNode))
     assert len(new_parents.difference(old_parents))==0
     assert len(old_parents.difference(new_parents))==1