lesteve: For the record, an excerpt of the output from the snippet in #420 (on this PR):

```
---------------------------------------------------------------------------
Sub-process traceback:
---------------------------------------------------------------------------
ZeroDivisionError                                  Wed Dec  7 15:16:32 2016
PID: 22133                Python 3.5.2: /home/lesteve/miniconda3/bin/python
...........................................................................
/home/lesteve/dev/joblib/joblib/parallel.py in __call__(self=<joblib.parallel.BatchedCalls object>)
    126     def __init__(self, iterator_slice):
    127         self.items = list(iterator_slice)
    128         self._size = len(self.items)
    129 
    130     def __call__(self):
--> 131         return [func(*args, **kwargs) for func, args, kwargs in self.items]
        self.items = [(<function exception_on_even>, (2,), {})]
    132 
    133     def __len__(self):
    134         return self._size
    135 

...........................................................................
/home/lesteve/dev/joblib/joblib/parallel.py in <listcomp>(.0=<list_iterator object>)
    126     def __init__(self, iterator_slice):
    127         self.items = list(iterator_slice)
    128         self._size = len(self.items)
    129 
    130     def __call__(self):
--> 131         return [func(*args, **kwargs) for func, args, kwargs in self.items]
        func = <function exception_on_even>
        args = (2,)
        kwargs = {}
    132 
    133     def __len__(self):
    134         return self._size
    135 

...........................................................................
/tmp/test_module.py in exception_on_even(x=2)
      1 def exception_on_even(x):
      2     if x % 2 == 0:
----> 3         1/0
      4     else:
      5         return x

ZeroDivisionError: division by zero
___________________________________________________________________________
```
lesteve: OK I am quite happy with the tests I added and I don't think there was any strong reason for the padding, so I am going to merge this one.

@GaelVaroquaux @ogrisel shout if you see any issue with this and I'll revert it.
diff --git a/joblib/format_stack.py b/joblib/format_stack.py
index 3f3d106..4be93c1 100644
--- a/joblib/format_stack.py
+++ b/joblib/format_stack.py
@@ -135,15 +135,10 @@ def _fixed_getframes(etb, context=1, tb_offset=0):
     aux = traceback.extract_tb(etb)
     assert len(records) == len(aux)
     for i, (file, lnum, _, _) in enumerate(aux):
-        maybeStart = lnum - 1 - context // 2
-        start = max(maybeStart, 0)
+        maybe_start = lnum - 1 - context // 2
+        start = max(maybe_start, 0)
         end = start + context
         lines = linecache.getlines(file)[start:end]
-        # pad with empty lines if necessary
-        if maybeStart < 0:
-            lines = (['\n'] * -maybeStart) + lines
-        if len(lines) < context:
-            lines += ['\n'] * (context - len(lines))
         buf = list(records[i])
         buf[LNUM_POS] = lnum
         buf[INDEX_POS] = lnum - 1 - start
@@ -400,15 +395,10 @@ def format_outer_frames(context=5, stack_start=None, stack_end=None,
             if (os.path.basename(filename) in ('iplib.py', 'py3compat.py')
                         and func_name in ('execfile', 'safe_execfile', 'runcode')):
                 break
-        maybeStart = line_no - 1 - context // 2
-        start = max(maybeStart, 0)
+        maybe_start = line_no - 1 - context // 2
+        start = max(maybe_start, 0)
         end = start + context
         lines = linecache.getlines(filename)[start:end]
-        # pad with empty lines if necessary
-        if maybeStart < 0:
-            lines = (['\n'] * -maybeStart) + lines
-        if len(lines) < context:
-            lines += ['\n'] * (context - len(lines))
         buf = list(records[i])
         buf[LNUM_POS] = line_no
         buf[INDEX_POS] = line_no - 1 - start

Wrong line pointed to in subprocess traceback
test.py
```py
from test_module import exception_on_even

from joblib import Parallel, delayed

if __name__ == '__main__':
    Parallel(n_jobs=2)(delayed(exception_on_even)(x) for x in [1, 2, 3])
```

test_module.py
```py
def exception_on_even(x):
    if x % 2 == 0:
        1/0
    else:
        return x
```

Excerpt from the Traceback when running `ipython test.py`:
```
---------------------------------------------------------------------------
Sub-process traceback:
---------------------------------------------------------------------------
ZeroDivisionError                                  Wed Nov  2 09:52:46 2016
PID: 7267                 Python 3.5.2: /home/lesteve/miniconda3/bin/python
...........................................................................
/home/lesteve/dev/joblib/joblib/parallel.py in __call__(self=<joblib.parallel.BatchedCalls object>)
    126     def __init__(self, iterator_slice):
    127         self.items = list(iterator_slice)
    128         self._size = len(self.items)
    129 
    130     def __call__(self):
--> 131         return [func(*args, **kwargs) for func, args, kwargs in self.items]
        self.items = [(<function exception_on_even>, (2,), {})]
    132 
    133     def __len__(self):
    134         return self._size
    135 

...........................................................................
/home/lesteve/dev/joblib/joblib/parallel.py in <listcomp>(.0=<list_iterator object>)
    126     def __init__(self, iterator_slice):
    127         self.items = list(iterator_slice)
    128         self._size = len(self.items)
    129 
    130     def __call__(self):
--> 131         return [func(*args, **kwargs) for func, args, kwargs in self.items]
        func = <function exception_on_even>
        args = (2,)
        kwargs = {}
    132 
    133     def __len__(self):
    134         return self._size
    135 

...........................................................................
/tmp/test_module.py in exception_on_even(x=2)
      1 
      2 
----> 3 
      4 def exception_on_even(x):
      5     if x % 2 == 0:
      6         1/0
      7     else:
      8         return x
      9 
     10 

ZeroDivisionError: division by zero
```

The arrow in the last frame points to line 3 whereas it should point to line 6.
diff --git a/joblib/test/test_format_stack.py b/joblib/test/test_format_stack.py
index 32fc8f5..baa8076 100644
--- a/joblib/test/test_format_stack.py
+++ b/joblib/test/test_format_stack.py
@@ -6,6 +6,8 @@ Unit tests for the stack formatting utilities
 # Copyright (c) 2010 Gael Varoquaux
 # License: BSD Style, 3 clauses.
 
+import imp
+import os
 import re
 import sys
 
@@ -75,6 +77,38 @@ def test_format_records():
                          re.MULTILINE)
 
 
+def test_format_records_file_with_less_lines_than_context(tmpdir):
+    # See https://github.com/joblib/joblib/issues/420
+    filename = os.path.join(tmpdir.strpath, 'small_file.py')
+    code_lines = ['def func():', '    1/0']
+    code = '\n'.join(code_lines)
+    open(filename, 'w').write(code)
+
+    small_file = imp.load_source('small_file', filename)
+    try:
+        small_file.func()
+    except ZeroDivisionError:
+        etb = sys.exc_info()[2]
+
+        records = _fixed_getframes(etb, context=10)
+        # Check that if context is bigger than the number of lines in
+        # the file you do not get padding
+        frame, tb_filename, line, func_name, context, _ = records[-1]
+        assert [l.rstrip() for l in context] == code_lines
+
+        formatted_records = format_records(records)
+        # 2 lines for header in the traceback: lines of ...... +
+        # filename with function
+        len_header = 2
+        nb_lines_formatted_records = len(formatted_records[1].splitlines())
+        assert (nb_lines_formatted_records == len_header + len(code_lines))
+        # Check exception stack
+        arrow_regex = r'^-+>\s+\d+\s+'
+        assert re.search(arrow_regex + r'1/0',
+                         formatted_records[1],
+                         re.MULTILINE)
+
+
 @with_numpy
 def test_format_exc_with_compiled_code():
     # Trying to tokenize compiled C code raise SyntaxError.

pip install -e .
parse_log_pytest
pytest
numpy>=1.6.1 pytest pytest-cov
apt-get update apt-get install -y gcc
3.9
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
coverage==7.8.0
exceptiongroup @ file:///croot/exceptiongroup_1706031385326/work
iniconfig @ file:///home/linux1/recipes/ci/iniconfig_1610983019677/work
-e git+https://github.com/joblib/joblib.git@aab21b654e853616b31c6e50255b2dcf47af5818#egg=joblib
numpy==2.0.2
packaging @ file:///croot/packaging_1734472117206/work
pluggy @ file:///croot/pluggy_1733169602837/work
pytest @ file:///croot/pytest_1738938843180/work
pytest-cov==6.0.0
tomli @ file:///opt/conda/conda-bld/tomli_1657175507142/work

name: joblib
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - exceptiongroup=1.2.0=py39h06a4308_0
  - iniconfig=1.1.1=pyhd3eb1b0_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=3.0.16=h5eee18b_0
  - packaging=24.2=py39h06a4308_0
  - pip=25.0=py39h06a4308_0
  - pluggy=1.5.0=py39h06a4308_0
  - pytest=8.3.4=py39h06a4308_0
  - python=3.9.21=he870216_1
  - readline=8.2=h5eee18b_0
  - setuptools=75.8.0=py39h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - tomli=2.0.1=py39h06a4308_0
  - tzdata=2025a=h04d1e81_0
  - wheel=0.45.1=py39h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - coverage==7.8.0
      - numpy==2.0.2
      - pytest-cov==6.0.0
prefix: /opt/conda/envs/joblib

joblib/test/test_format_stack.py::test_format_records_file_with_less_lines_than_context
joblib/test/test_format_stack.py::test_safe_repr joblib/test/test_format_stack.py::test_format_records joblib/test/test_format_stack.py::test_format_exc_with_compiled_code
joblib/format_stack.py
joblib/format_stack.py