Code

Opened 4 years ago

Closed 7 months ago

#12568 closed Bug (fixed)

SubFieldBase descriptor object should be accessible

Reported by: specialunderwear Owned by: nobody
Component: Forms Version: 1.2-alpha
Severity: Normal Keywords: SubFieldBase subclassing
Cc: Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: yes Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Currently any field that has SubFieldBase as a metaclass will throw an exception if you try access the descriptor object without an instance.
Things like the following can not be done with the current implementation:

    def _get_members_of_type(obj, member_type):
        """
        Finds members of a certain type in obj.
        """
        def filter_member_type(member):
            try:
                return type(member) is member_type
            except AttributeError:
                return False
                
        # if the type of obj is the metaclass for all models, just search in the object
        # because it is not a model instance but a type
        if type(obj) is ModelBase:
            key_hash = inspect.getmembers(obj, filter_member_type)
        else:
            key_hash = inspect.getmembers(obj.__class__, filter_member_type)
            

        return key_hash

SubFieldBase will throw an AttributeError every time inspect.getmembers is used on a model instance or class.
Normal behaviour would be to return the descriptor object when no instance is passed. All django's standard fields
behave this way, so it would be best if SubFieldBase would do the same.

I will attach a patch against current trunk.

Attachments (3)

subfieldbase-fix.diff (502 bytes) - added by specialunderwear 4 years ago.
subfieldbase_fix_and_test.diff (1.3 KB) - added by specialunderwear 4 years ago.
This time the test is also added
subfieldbase-20130917.diff (1.6 KB) - added by supervacuo 7 months ago.
Rebased against git master (5be56d0)

Download all attachments as: .zip

Change History (15)

Changed 4 years ago by specialunderwear

comment:1 Changed 4 years ago by specialunderwear

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset

More specific:

SubFieldBase? will throw an AttributeError? every time inspect.getmembers is used on a model instance or class that has fields which use SubFieldBase.

comment:2 Changed 4 years ago by russellm

  • Needs tests set
  • Triage Stage changed from Unreviewed to Accepted

comment:3 Changed 4 years ago by russellm

  • Component changed from Uncategorized to Forms

comment:4 Changed 4 years ago by ubernostrum

  • milestone 1.2 deleted

1.2 is feature-frozen, moving this feature request off the milestone.

comment:5 Changed 4 years ago by specialunderwear

I added a new patch + tests to fix this issue in 1.2
Please do not let descriptors break inspect, but instead behave like a proper property, which returns self when a descriptor is accessed without context:

http://users.rcn.com/python/download/Descriptor.htm#properties

If you need the descriptor object itself to be inaccessible for some reason, just return None instead of self. This would also make more sense, an uninitialized property is None, just like a regular attribute.

There are more places where the AttributeError is thrown, for instance ManagerDescriptor raises:

AttributeError: Manager isn't accessible via MyModel instances

When a model instance is inspected.

ImageField and FileField also do it, which to me seems wrong.

Changed 4 years ago by specialunderwear

This time the test is also added

comment:6 Changed 3 years ago by mattmcc

  • Severity set to Normal
  • Type set to Bug

comment:7 Changed 2 years ago by aaugustin

  • UI/UX unset

Change UI/UX from NULL to False.

comment:8 Changed 2 years ago by aaugustin

  • Easy pickings unset

Change Easy pickings from NULL to False.

Changed 7 months ago by supervacuo

Rebased against git master (5be56d0)

comment:9 Changed 7 months ago by supervacuo

Any chance this can make it into an official release? I'm happy to polish up however needed, or take this to django-developers if it really needs discussion.

Rebased patch against git master attached above, as a start.

This bug causes an AttributeError when trying to use sphinx-autodoc on custom fields which have __metaclass__ = SubFieldBase, due to the underlying "must be accessed from instance" AttributeError. The equivalent ticket for fixing inspect() for Django's built-in fields was #8248, fixed in [9634] (~5 years ago).

comment:10 Changed 7 months ago by anonymous

Nice!

comment:11 Changed 7 months ago by akaariai

Any objections for adding this, seems like a good addition to me?

comment:12 Changed 7 months ago by Anssi Kääriäinen <akaariai@…>

  • Resolution set to fixed
  • Status changed from new to closed

In 50633e7353694ff54f14b04469be3792f286182f:

Fixed #12568 -- no error when accessing custom field's descriptor

The SubfieldBase's descriptor caused an AttributeError when accessed
from the class. Introspection didn't like that.

Patch by Trac alias supervacuo.

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
as The resolution will be set. Next status will be 'closed'
The resolution will be deleted. Next status will be 'new'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.