Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal: py2neo.ogm descriptors are difficult to get #784

Open
motey opened this issue Jan 29, 2020 · 1 comment
Open

Proposal: py2neo.ogm descriptors are difficult to get #784

motey opened this issue Jan 29, 2020 · 1 comment

Comments

@motey
Copy link

motey commented Jan 29, 2020

I am trying to inspect a py2neo.ogm.GraphObject subclass. I want to check if a certain class attribute is a py2neo.ogm.Property:

from py2neo.ogm import Property, GraphObject
class Entity(GraphObject):
    name = Property()
print(type(getattr(Entity, "name")))

This will fail as with getattr(Entity, "name") py2neo.ogm.Property.__get__() will be called and raises an

AttributeError: 'NoneType' object has no attribute '__node__'

One workaround is to check my classes __dict__

print(type(Entity.__dict__["name"]))

This will return '<class 'py2neo.ogm.Property'>'
Now i know that Entity.name is py2neo.ogm.Property. Nice...But:

This will fail as soon the Property is inherited.

from py2neo.ogm import Property, GraphObject
class Entity(GraphObject):
    name = Property()
class Person(Entity):
    pass
print(type(Person.__dict__["name"]))

This will fail with a "KeyError: 'name'" as 'name' is in the superclass Entity.

I could now start to traverse all subclasses and search for the attr.

Another solution is to add an instance check to all py2neo.ogm descriptors

py2neo/internal/ogm.py[z41]:

[...]
class Property(object):
[...]
ef __get__(self, instance, owner):
        if instance is None:
            return self
[...]

now we easily could create a neat helper func like:

def get_graphobjectclass_property_keys(cls, graphobjectclass) -> [str]:
	return [
	    propname
	    for propname in dir(graphobjectclass)
	    if isinstance(getattr(graphobjectclass,propname), Property)
	]
  • Whats you opinion on that?
  • Do you know a better way to achive my goal

Related discussion on stackoverflow:
https://stackoverflow.com/questions/21629397/neat-way-to-get-descriptor-object

I will create a merge request for the changes.

@technige
Copy link
Member

Hi @motey. Thanks for raising this, I can see that it's a valid gap in the functionality. Your proposal feels like it's along the right lines, but I'm going to give some thought to slightly broader functionality around reflection of GraphObjects. Watch this space.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Work Tracker
Feature Requests
Development

No branches or pull requests

2 participants