Why doesn't inspect.getsource return the whole class source?
-
06-09-2019 - |
Question
I have this code in my forms.py
:
from django import forms
from formfieldset.forms import FieldsetMixin
class ContactForm(forms.Form, FieldsetMixin):
full_name = forms.CharField(max_length=120)
email = forms.EmailField()
website = forms.URLField()
message = forms.CharField(max_length=500, widget=forms.Textarea)
send_notification = forms.BooleanField(required=False)
fieldsets = ((u'Personal Information',
{'fields': ('full_name', 'email', 'website'),
'description': u'Your personal information will not ' \
u'be shared with 3rd parties.'}),
(None,
{'fields': ('message',),
'description': u'All HTML will be stripped out.'}),
(u'Preferences',
{'fields': ('send_notification',)}))
When I try to extract the code programmatically with inspect
it leaves out fieldsets
:
In [1]: import inspect
In [2]: import forms
In [3]: print inspect.getsource(forms)
from django import forms
from formfieldset.forms import FieldsetMixin
class ContactForm(forms.Form, FieldsetMixin):
full_name = forms.CharField(max_length=120)
email = forms.EmailField()
website = forms.URLField()
message = forms.CharField(max_length=500, widget=forms.Textarea)
send_notification = forms.BooleanField(required=False)
fieldsets = ((u'Personal Information',
{'fields': ('full_name', 'email', 'website'),
'description': u'Your personal information will not ' \
u'be shared with 3rd parties.'}),
(None,
{'fields': ('message',),
'description': u'All HTML will be stripped out.'}),
(u'Preferences',
{'fields': ('send_notification',)}))
In [4]: print inspect.getsource(forms.ContactForm)
class ContactForm(forms.Form, FieldsetMixin):
full_name = forms.CharField(max_length=120)
email = forms.EmailField()
website = forms.URLField()
message = forms.CharField(max_length=500, widget=forms.Textarea)
send_notification = forms.BooleanField(required=False)
In [5]:
This doesn't seem to be an issue with blank lines. I've tested without the blank line in between and I've put additional blank lines in between other attributes. Results don't change.
Any ideas why inspect is returning only the part before fieldsets
and not the whole source of the class?
Solution
edit: revised based on comments:
Inside inspect.getsource(forms.ContactForm)
the method BlockFinder.tokeneater()
is used to determine where the ContactForm
block stops. Besides others, it checks for tokenize.DEDENT
, which it finds right before fieldsets in your version stored at github. The line contains only a line break, so inspect
thinks the current block has ended.
If you insert 4 spaces, it works for me again. I cannot argue on the rationale behind this, maybe performance.
class ContactForm(forms.Form):
full_name = forms.CharField(max_length=120)
email = forms.EmailField()
website = forms.URLField()
message = forms.CharField(max_length=500, widget=forms.Textarea)
send_notification = forms.BooleanField(required=False)
# <-- insert 4 spaces here
fieldsets = ((u'Personal Information',
{'fields': ('full_name', 'email', 'website'),
'description': u'Your personal information will not ' \
u'be shared with 3rd parties.'}),
(None,
{'fields': ('message',),
'description': u'All HTML will be stripped out.'}),
(u'Preferences',
{'fields': ('send_notification',)}))
The reason that inspect.getsource(forms)
works differently is because inspect
in that case does not have to determine the class definition's start and end. It simply outputs the whole file.
OTHER TIPS
Works for me. I don't have "from formfieldset.forms import FieldsetMixin" in my code. Maybe that is causing an issue..