[issue46073] ast.unparse produces: 'FunctionDef' object has no attribute 'lineno' for valid module

Nikita Sobolev report at bugs.python.org
Tue Dec 14 16:32:52 EST 2021


Nikita Sobolev <mail at sobolevn.me> added the comment:

Or, maybe this is a correct thing to do. Consider this case. Let's say we now check that `node` has `lineno` and exclude ones that don't.

Then, we write this test (in `Lib/test/test_unparse`):

```
    def test_unparse_nodes_without_lineno(self):
        # https://bugs.python.org/issue46073
        def create_module(ignores):
            return ast.Module(
                body=[
                    ast.FunctionDef(
                        name="items_needed",
                        args=ast.arguments(
                            posonlyargs=[], args=[],
                            kwonlyargs=[], kw_defaults=[], defaults=[],
                        ),
                        body=[ast.Pass()], decorator_list=[],
                    ),
                ],
                type_ignores=ignores,
            )

        ast1 = create_module([])
        self.assertASTEqual(ast1, ast.parse(ast.unparse(ast1)))

        ast2 = create_module([ast.TypeIgnore(lineno=1, tag='')])
        # This fill fail without `ast2 = ast.fix_missing_locations(ast2)`
        self.assertASTEqual(ast2, ast.parse(ast.unparse(ast2), type_comments=True))
```

In this case the second `assert` will fail, because the resulting codes would be different:

```
# "original"
def items_needed():  # type: ignore
    pass

# unparsed
def items_needed():
    pass
```

So, basically users will get different code. Which is not a good thing.

So, maybe raising an error that some `node` does not have `lineno` is good after all?

----------

_______________________________________
Python tracker <report at bugs.python.org>
<https://bugs.python.org/issue46073>
_______________________________________


More information about the Python-bugs-list mailing list