berkerpeksag / astor

Python AST read/write
https://pypi.org/project/astor/
BSD 3-Clause "New" or "Revised" License
803 stars 102 forks source link

Checking subclass in to_source function #158

Closed hankliu5 closed 4 years ago

hankliu5 commented 5 years ago

Hello,

I have a question about the function to_source() in code_gen.py. The reference is below: https://github.com/berkerpeksag/astor/blob/ef8a6559641967bcadd4f1e08a2ed6dec8311542/astor/code_gen.py#L54-L59

Since the message in line 57 mentions that line 56 means to check whether source_generator_class is the subclass of astor.code_gen.SourceGenerator or not, should line 56 uses issubclass(source_generator_class, astor.code_gen.SourceGenerator)?

Thanks for your answer.

berkerpeksag commented 5 years ago

Hello, thank you for your report. isinstance(a, b) also does check whether a is a subclass of b. Did you get any non-expected behavior with the current isinstance usage?

hankliu5 commented 5 years ago

Hello,

Thanks for your quick reply. I followed the example from #113 and #114, and here is my source code

import astor
import ast
from astor.string_repr import pretty_string
from astor.source_repr import pretty_source
class SubSourceGenerator(astor.code_gen.SourceGenerator):
    def __init__(self, indent_with, add_line_information=False,
                 pretty_string=pretty_string,
                 # constants
                 len=len, isinstance=isinstance, callable=callable):
        super().__init__(indent_with, add_line_information, pretty_string, len, isinstance, callable)

node = ast.parse('a=1')
astor.to_source(node, source_generator_class=SubSourceGenerator)

Then I got:

Traceback (most recent call last):
  File "<input>", line 15, in <module>
  File "/Users/hankliu/PycharmProjects/py_to_cy/venv/lib/python3.5/site-packages/astor/code_gen.py", line 57, in to_source
    raise TypeError('source_generator_class should be a subclass of SourceGenerator')
TypeError: source_generator_class should be a subclass of SourceGenerator

Then I tried both isinstance and issubclass functions:

issubclass(SubSourceGenerator, astor.code_gen.SourceGenerator)
>>> True

isinstance(SubSourceGenerator, astor.code_gen.SourceGenerator)
>>> False

isinstance(SubSourceGenerator(' '*4), astor.code_gen.SourceGenerator)
>>> True

isinstance(SubSourceGenerator(), astor.code_gen.SourceGenerator)

Traceback (most recent call last):
  File "<input>", line 1, in <module>
TypeError: __init__() missing 1 required positional argument: 'indent_with'

The Python version is 3.5.7. Thanks for your help and your amazing tool :).

berkerpeksag commented 5 years ago

Ah, now I got your point! Thank you for the reproducer. That's definitely my mistake, sorry for the trouble. PR #151 should fix that faulty check. I'll try to get it merged this weekend.

hankliu5 commented 5 years ago

Yeah, PR #151 is the one I'd like to propose and fix. Thanks for checking that bug.