Skip to content

Add add_foo() methods for EntityList foo properties #117

Open

Description

@bworrell

The introduction of EntityList greatly helped reduce the amount of code needed to write for python-stix classes, but also established a new pattern for working with list types. We should go back through the codebase and add the add_foo() methods where missing. This is related to #110.

Activity

  1. gtback commented on Apr 17, 2014

    @gtback
    Contributor

    I generally dislike this approach (which is why I never add them to classes 😉). It feels unpythonic to me, and more like Java or the generateDS bindings. The goal of EntityList is to make interacting with these list types feel exactly like working with Python lists, while supporting the XML import and export and enforcing the type of items that are allowed in the list, without a lot of boilerplate code.

    I suppose for the sake of consistency it would be good to add them (though I would prefer removing all the others 😀).

    You could also use some magic Python and put this (WARNING: pseudocode) on the stix.Entity class to prevent the boilerplate code:

    def __getattr__(self, name):
        if not name.startswith("add_"):
            return object.__getattr__(self, name)
        # get everything after the first _
        real_attr = name.split("_", 1)[1]
        # return the append() function of whatever type is trying to be added,
        # which then gets called with whatever argument the caller tried to pass.
        return getattr(self, real_attr).append

    I haven't actually tried running that function, but something like that is better (IMO) than 73 copies of almost-identical functions scattered throughout the code.

  2. bworrell commented on Apr 17, 2014

    @bworrell
    ContributorAuthor

    Hmm, this might work, though it would require ripping out all the old add_foo() functions and converting many of our list fields to EntityList instances..or checking to see if that add_foo() function already exists and returning it if it does.

    ...
    if hasattr(self, name):
        return object.__getattr__(self, name)
    ...
  3. gtback commented on Apr 17, 2014

    @gtback
    Contributor

    It might just work as is, meaning we can leave the existing functions as is for now (that is, until I convince you to remove them 😉)

    object.__getattr__(self, name)
    Called when an attribute lookup has not found the attribute in the usual places (i.e. it is not an instance attribute nor is it found in the class tree for self). name is the attribute name. This method should return the (computed) attribute value or raise an AttributeError exception.

    Note that if the attribute is found through the normal mechanism, __getattr__() is not called. (This is an intentional asymmetry between __getattr__() and __setattr__().) This is done both for efficiency reasons and because otherwise __getattr__() would have no way to access other attributes of the instance.

    https://docs.python.org/2/reference/datamodel.html#object.__getattr__

    Again, I haven't actually tested any of this.

  4. bworrell commented on Apr 17, 2014

    @bworrell
    ContributorAuthor

    Oh, nice! I was wondering if that was the behavior and considered looking up the docs...but didn't ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions