MongoEngine / MongoEngine/mongoengine

LazyReference field attribute error on access

Open
#2,165 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
4.3k
Forks
1.2k
Avg merge
4h 41m
Merged PRs (30d)
11

Description

This happens on python version 3.7.4 and 3.6.8 using
mongoengine version from 0.15.3 up to 0.18.2

Code works correctly on python version 3.6.8 with mongoversion 0.15

Starting from a clean python installation, only dependency installed mongoengine.

When trying to access an attribute from one of a reference, instead of fetching the reference or either failing to get the data without manually doing a fetch it fails way before.

verification.py is the snippet of code found below:

  File "verification.py", line 41, in <module>
    print(match.status)
  File "C:\Users\sinap\scoop\apps\python\current\lib\site-packages\mongoengine\base\datastructures.py", line 468, in __getattr__
    raise AttributeError()
AttributeError

The code that fails is

    def __getattr__(self, name):
        if not object.__getattribute__(self, 'passthrough'):
            raise AttributeError()
        document = self.fetch()

so is trying to define if it needs to fetch or not by configuration attribute passthrough, but it never gets the chance because the code fails at that point.

This is a sample code that I made to test this case:

# -*- coding: utf-8 -*-
import logging
import mongoengine
from mongoengine import fields
from mongoengine import connect

# -*- coding: utf-8 -*-
import logging
import mongoengine
from mongoengine import fields
from mongoengine import connect
from mongoengine.connection import get_db

class SomethingToMatch(mongoengine.Document):
    status = fields.StringField(required=True)

    def get_status(self):
	    return "status"


class MatcheableExperiment(mongoengine.Document):
    status = fields.StringField(required=True)
    matches = fields.ListField(fields.LazyReferenceField("SomethingToMatch", passthrough= True))


DATABASE = {"host": "localhost", "port": 27017, "db": "MADIBA", "username": "", "password": ""}

connect(**DATABASE, connect=False)


first = SomethingToMatch(status="Here")
first.save()

match = MatcheableExperiment(status="where")
match.matches = [first]
match.save()

db_object = MatcheableExperiment.objects(id=match.id).get()
for match in db_object.matches:
    print(match.get_status())

I have check and in tag version v0.15.1 it was already broken.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the reproduction in verification.py and inspect mongoengine/base/datastructures.py around getattr at line 468. Reproduce the LazyReference access with passthrough=True across the reported versions, then verify that accessing the reference attribute no longer raises AttributeError before fetching.

Written by the indexing model from the issue text.

Assessment

Tech stack
mongodb, python
Domain
databases
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.