Repository: pylint-dev/astroid

Issue:
``nodes.Module`` don't have a ``end_lineno`` and ``end_col_offset``
### Steps to reproduce

```python
import astroid

code = """
    print("a module")
    """

module = astroid.parse(code)
print(module.end_lineno)
print(module.end_col_offset)
```

### Current behavior

`AttributeError` on both of the last lines.

### Expected behavior

@cdce8p Let me know if I misunderstood you, but I thought we wanted these to be accessible on all nodes, just initialised as `None`.
If that was not the case, I would make the case to do so as it allows you to do `node.end_lineno` without running in to `AttributeError`'s.

### Version

Latest `main`.



Discussion / hints:

Fix (patch):
diff --git a/ChangeLog b/ChangeLog
index 3b026ba905..9641cf0441 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -18,6 +18,9 @@ Release date: TBA
 
   Closes #1260
 
+* Fix ``Module`` nodes not having a ``col_offset``, ``end_lineno``, and ``end_col_offset``
+  attributes.
+
 * Fix typing and update explanation for ``Arguments.args`` being ``None``.
 
 * Fix crash if a variable named ``type`` is subscripted in a generator expression.
diff --git a/astroid/nodes/scoped_nodes.py b/astroid/nodes/scoped_nodes.py
index 0c745a4fca..96a034c868 100644
--- a/astroid/nodes/scoped_nodes.py
+++ b/astroid/nodes/scoped_nodes.py
@@ -389,10 +389,8 @@ class Module(LocalsDictNodeNG):
 
     :type: int or None
     """
-    lineno = 0
+    lineno: Literal[0] = 0
     """The line that this node appears on in the source code.
-
-    :type: int or None
     """
 
     # attributes below are set by the builder module or by raw factories
@@ -469,7 +467,6 @@ class Module(LocalsDictNodeNG):
     )
     _other_other_fields = ("locals", "globals")
 
-    lineno: None
     col_offset: None
     end_lineno: None
     end_col_offset: None
@@ -512,7 +509,6 @@ def __init__(
         self.file = file
         self.path = path
         self.package = package
-        self.parent = parent
         self.pure_python = pure_python
         self.locals = self.globals = {}
         """A map of the name of a local variable to the node defining the local.
@@ -526,6 +522,8 @@ def __init__(
         """
         self.future_imports = set()
 
+        super().__init__(lineno=0, parent=parent)
+
     # pylint: enable=redefined-builtin
 
     def postinit(self, body=None):


Test changes:
diff --git a/tests/unittest_nodes_lineno.py b/tests/unittest_nodes_lineno.py
index 75d664dc48..73cf0207cc 100644
--- a/tests/unittest_nodes_lineno.py
+++ b/tests/unittest_nodes_lineno.py
@@ -2,6 +2,7 @@
 
 import pytest
 
+import astroid
 from astroid import builder, nodes
 from astroid.const import PY38_PLUS, PY39_PLUS, PY310_PLUS
 
@@ -1221,3 +1222,14 @@ class X(Parent, var=42):
         assert (c1.body[0].lineno, c1.body[0].col_offset) == (4, 4)
         assert (c1.body[0].end_lineno, c1.body[0].end_col_offset) == (4, 8)
         # fmt: on
+
+    @staticmethod
+    def test_end_lineno_module() -> None:
+        """Tests for Module"""
+        code = """print()"""
+        module = astroid.parse(code)
+        assert isinstance(module, nodes.Module)
+        assert module.lineno == 0
+        assert module.col_offset is None
+        assert module.end_lineno is None
+        assert module.end_col_offset is None