Class structure in Gramps: primary object

Creating a class using each syntax and checking their class and baseclass, both appear to be defined similarly, each being of class ‘type’ derived from class ‘object’:


>>> class newClass:
...     pass
...
>>> newClass.__class__
<class 'type'>
>>> newClass.__class__.__base__
<class 'object'>


>>> class objClass(object):
...     pass
...
>>> objClass.__class__
<class 'type'>
>>> objClass.__class__.__base__
<class 'object'>

BTW, I’m no Python expert - this is a learning experiment for me.

@codefarmer: thanks for experimenting

However, still according to the Python manual, I think inheritance is not the full story. It is clearly stated that the top class tree structure is rather “twisted”.

I think the main difference comes from object being a “featureless” (see manual) object and type is a metaclass (used to create classes instead of instances). Therefore object has class type (clearly shown by your example) and type has also class type because everything in Python must derive from some class. Both are Python objects (a container for the representation data) at top level which is confirmed by __base__ value.

Notation class xxx(object): was necessary under Python 2 to create “new style” classes which are now the default under Python 3. Thus (object) can be dropped without adverse effects.

But this is not the same for class yyy(type): which creates a metaclass while class yyy: creates an ordinary class. It can make a difference in some contexts.

Agreed! Using dir((yyy) and comparing to dir(xxx) showed quite a few differences. Not having used metaclasses in Python, this was a good discussion to follow.

Nope. If I read correctly the Python manual, class xxx: creates a class derived from type , i.e. it already inherits a certain number of methods. class xxx(object): creates a much poorer class with nearly no methods.

Sorry, but then you’re reading it wrong. They are equivalent.

I was looking at the File:API.svg file information (the UML diagram), its (3 revision) history, and the pages to which it is linked in the wiki. The older (Feb 2012 and Dec 2010) revisions are without the obscuring connector lines found in the May 2014 revision.

But it makes me wonder if there is documentation on how a moving target like these diagrams are generated? The UML diagram was last updated in 2014. Perhaps @romjerome has a workflow documented for generating a UML diagram and could post it? (Like @sam888 did for the Rollover for the manual and @GaryGriffin did for the offline manual generation.) Kari just did a supertool.svg of his variable shorthand for the Reference section of the SuperTool manual. But Isotammi runs parallel development because they find our process too convoluted.

The new Primary Object class structure diagram by @pgerlier hasn’t been posted to the wiki yet. There wasn’t enough feedback to determine (by a non-programmer) if it has evolved to its final form nor where it should be linked in the wiki.

Maybe these conceptual outlines should be gathered in a data diagrams section of the Developer Docs in the Sphinx CMS? (With their generation process documented so they can be updated.)

another example is the source of the images(s) composited as a background for our Wordpress page:


The center photo is of Bert Allingham Jr. (Don’s “Gramps”). But where did the rest of the image come from? Is it public domain?

And it is good because I found errors in my diagrams. My reading of the code at that time was not deep enough. The diagram at top of this topic illustrates (partially) class relations. Since then I have designed new diagrams focused on genealogical record structure (loosely related to classes) which better show the relationship in each category instead of a cluttered global view.

The UML diagram, being global, encompasses all possible relations and suggests some which do not exist for specific records.

See one of the new diagrams:

Regarding its “generation process”, it is fully manual after careful reading of the code (therefore the possible errors). My diagrams are “SQL-oriented”. I mean I try to design an SQL schema to natively store genealogical data outside BLOBs. This is why you see boxes labelled reference to denote indirect access to arrays (parallel to m:n relationship implementation in SQL). Coloured boxes are Gramps classes. Fields internal to classes are omitted to keep diagrams simple.

1 Like

Ran across GEPS013 : Gramps Webapp with a File:All-tables.png diagram showing the types for each Gramps3.x data element. Does that diagram (or a modern update) have any value?


It also has a tip about regenerating the diagram:
"To update this (Gramps 3.x and earlier) |2=To see more graphical representations of the data, run “make docs” in the src/webapp/ directory, and then look in src/webapp/docs/.

(The only branch where I find a folder with the webapp name is in maintenance/gramps40/ and there is a makefile for docs.)

This a similar to the UML diagram and it has the same inconveniences.

It shows a global view without taking into consideration the specificities of the primary objects. Not all secondary objects make sense from a specific primary object. This is why I draw ad hoc partial diagrams for each primary. Otherwise you make wrong conclusions from the global diagram and you can even end up in loops.

1 Like

Thanks Patrick. I’m trying to find diagrams that help a newbie get started experimenting with the manipulation of tree data with Python. The part that I liked in this last diagram was that it showed what type of data could be expected to be stored.

A collection of basic references is being added to the Help of SuperTool:

From my experiments, SuperTool has been easier to use as experimenting framework than the Python Shell Gramplet. It allows trying a single statement or a whole function. You can use or ignore the SuperTool shorthand variables or the Gramps Simple Access. Or drop down to the Gramps API or generic Python.

And it can all be done in a safe way. All the manipulations happen with Proxy Objects rather than the production data. Changes are only applied to Production if you use “Commit Changes”

So the idea is to cross-reference the resources and show how to evolve an idea through SuperTool experiments to a final addon with GUI.

(There was a Query Grampet for doing SQL experiments but it was withdrawn a few years ago by its creator. Like the Python Shell, it wasn’t a sandbox approach.)

I am working on the core of Gramps, implying changes in the definition of base classes like PrimaryObject. This has big impact and I can’t use add-on tools (like SuperTool i was not aware of). I duplicated the whole Gramps source code under a separate account on my PC and don’t use my real data.

I have however a feeling that the whole implementation should be rewritten because there have been two many patches over the base code.

One of the biggest problems is genealogical data management has been tailored for GUI and more specifically for GTK+ library. IMHO, storage management is not sufficiently decoupled from GUI handling making difficult the use of various storage backends.

As an example, a Gramps Person object when created contains not only data from storage Person but also bits which would optimally better be stored separately like reference arrays. It does not really matter in the present implementation which simulates BSDDB over SQL, heavily using opaque BLOBs. But this prohibits clean SQL storage. In particular, it complicates commit decision to the DB when a list of secondary objects is changed in a primary object. I should have a deep look at the standard code to see what happens when Cancel button is pressed.

For the time being, I have not yet considered how to deal with present data. I fear that my changes diverge to a point that only XML-import could handle the compatibility issue.

1 Like