42. project — project.py

Functions for managing a project in pyFormex.

42.1. Classes defined in module project

class project.SORTKEY(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)[source]

A class with debug items.

This class holds the defined debug items as attributes. Each debug topic is a binary value with a single bit set (a power of 2). Debug items can be combined with & (AND), | (OR) and ^ (XOR). Two extra values are defined: NONE switches off all debugging, ALL activates all debug items.

Examples

>>> print(SORTKEY['HUMAN'])
SORTKEY.HUMAN
split()[source]

Returns human, ignore, name, type

static combine(sortkey=0, **kargs)[source]

Combine parameters into a SORTKEY

>>> print(SORTKEY.combine(name=True, ignore=True))
SORTKEY.I
>>> print(SORTKEY.combine(TH=True, ignore=True))
SORTKEY.THI
class project.Project(filename=None, data={})[source]

Project: a collection of pyFormex data with persistent storage.

A pyFormex Project is a Python dict that can contain named data of any kind, and can be saved to a file to create persistence over different pyFormex sessions. The dict is a TrackedDict so it does know if anything has changed to its contents since the last save.

The Project class is used by pyFormex for the pyformex.PF where global variables from pyFormex scripts can be saved and made accessible to the GUI. While projects are mostly handled through the pyFormex GUI, notably the File/Project menu, the user may also create and handle his own Project objects from a script.

Initially Projects were stored in a dedicated format (PYF), but nowadays they can be saved in the newer PZF format as well.

Because of the way pyFormex Projects are written to file, there may be problems when trying to read a project file that was created with another pyFormex version. Problems may occur if the project contains data of a class whose implementation has changed, or whose definition has been relocated. Our policy is to provide backward compatibility: newer versions of pyFormex will normally read the older project formats. Saving is always done in the newest format, and these can generally not be read back by older program versions (unless you are prepared to do some hacking).

Warning

Compatibility issues.

Occasionally you may run into problems when reading back an old project file, especially when it was created by an unreleased (development) version of pyFormex. Because pyFormex is evolving fast, we can not test the full compatibility with every revision You can file a support request on the pyFormex support tracker. and we will try to add the required conversion code to pyFormex.

The project files are mainly intended as a means to easily save lots of data of any kind and to restore them in the same session or a later session, to pass them to another user (with the same or later pyFormex version), to store them over a medium time period. Occasionally opening and saving back your project files with newer pyFormex versions may help to avoid read-back problems over longer time.

For a problemless long time storage of Geometry type objects you may consider to write them to a pyFormex Geometry file (.pgf) instead, since this uses a stable ascii based format. It can however (currently) only store obects of class Geometry or one of its subclasses.

Parameters:
  • filename (path_like) –

    The name of the file where the Project data will be saved. If the file exists (and access is not w), it should be a previously saved Project and an attempt will be made to load the data from this file into the Project. If this fails, an error is raised.

    If the file exists and access is w, it will be overwritten, destroying any previous contents.

    If no filename is specified, a temporary file will be created when the Project is saved for the first time. The file with not be automatically deleted. The generated name can be retrieved from the filename attribute.

  • access (str, optional) –

    The access mode of the project file: ‘wr’ (default), ‘rw’, ‘w’ or ‘r’. If the string contains an ‘r’ the data from an existing file will be read into the Project. If the string starts with an ‘r’, the file should exist. If the string contains a ‘w’, the data can be written back to the file. The ‘r’ access mode is a read-only mode.

    access

    File must exist

    File is read

    File can be written

    r

    yes

    yes

    no

    rw

    yes

    yes

    yes

    wr

    no

    if it exists

    yes

    w

    no

    no

    yes

  • convert (bool, optional) – If True (default), and the file is opened for reading, an attempt is made to open old projects in a compatibility mode, doing the necessary conversions to new data formats. If convert is set to False, only the latest format can be read and older formats will generate an error.

  • signature (str, optional) – A text that will be written in the header record of the file. This can e.g. be used to record format version info.

  • compression (int (0-9)) – The compression level. For large data sets, compression leads to much smaller files. 0 is no compression, 9 is maximal compression. The default is 4.

  • binary (bool) – If False and no compression is used, storage is done in an ASCII format, allowing to edit the file. Otherwise, storage uses a binary format. Using binary=False is deprecated.

  • data (dict, optional) – A dict-like object to initialize the Project contents. These data may override values read from the file.

  • protocol (int,optional) – The protocol to be used in pickling the data to file. If not specified, the highest protocol supported by the pickle module is used.

sortkey

Specifies how the objects should be sorted by default. See the sort parameter of contents() for possible values and their meaning. The default is ‘h’.

Type:

str

display

Specifies what the returned list will contain. See the display parameter of contents() for possible values and their meaning.

Type:

str, optional

Examples

>>> d = dict(a=1,b=2,c=3,d=[1,2,3],e={'f':4,'g':5})
>>> P = Project()
>>> P.update(d)
>>> print(P)
Project contents:
* a: 1
* b: 2
* c: 3
* d: [1, 2, 3]
* e: {'f': 4, 'g': 5}
>>> from pyformex.filetools import TempFile
>>> with TempFile(suffix='.pzf') as tmp:
...     P.save(filename=tmp.path)
...     Q = P
...     P.clear()
...     print(len(P))
...     P.load(tmp.path)
...     P == Q
0
Path('...pzf')
True
contents(fname=None, *, clas=None, like=None, func=None, sort=None, display=None)[source]

Return a name list of objects that match the given criteria.

Parameters:
  • fname (str) – The name of one of the built-in or added filters.

  • clas (class | tuple of classes) – If provided, only instances of these class(es) are included.

  • like (str) – A Python regular expression, see re. If provided, only object names fully matching this RE are included.

  • func (function) – A function taking a (name, object) tuple as parameter and returning True or False. If provided, only object names returning True will be included.

  • sort (str, optional) –

    Specifies how the objects are sorted. One of:

    • ’’: no sorting, use object insertion order,

    • ’n’: sort on object name (lexical: ‘A2’ before ‘a1’),

    • ’h’: human sort on object name (‘a9’ before ‘a10’),

    • ’i’: sort on name ignoring case (‘a1’ before A1’),

    • ’hi’: human sort ignoring case (‘a9’ before ‘A10’),

    • ’tn’: first sort on type, then one name,

    • ’th’: first sort on type, then human sort on name,

    • ’ti’: first sort on type, then case ignoring sort on name,

    • ’thi’: first sort on type, the case ignoring human sort on name.

    If not provided (or None), the Project’s sortkey attribute is used, which defaults to ‘h’.

  • display (str, optional) – Specifies what the returned list will contain. If ‘Name’, returns only the name or the item. If ‘Name+Type’, returns a string ‘Name: Type’ for each item. If not provided, the Project’s display attribute is used, which defaults to ‘Name+Type’.

Returns:

list of str – The name, type or name+type of the objects matching the criteria.

Examples

>>> from pyformex.core import Mesh, TriSurface
>>> M = Mesh()
>>> M1 = Mesh(eltype='tri3')
>>> S = M1.toSurface()
>>> F = S.toFormex()
>>> P = Project(data={'M10':M, 'MS':S, 'MF':F, 'M2':M1, 'm3':M})
>>> P.contents()
['M2: Mesh', 'M10: Mesh', 'MF: Formex', 'MS: TriSurface', 'm3: Mesh']
>>> P.contents(clas=Mesh, display='Name')
['M2', 'M10', 'MS', 'm3']
>>> P.display = 'Name'
>>> P.contents(sort='')
['M10', 'MS', 'MF', 'M2', 'm3']
>>> P.contents(sort='h')
['M2', 'M10', 'MF', 'MS', 'm3']
>>> P.contents(sort='i')
['M10', 'M2', 'm3', 'MF', 'MS']
>>> P.contents(sort='hi')
['M2', 'm3', 'M10', 'MF', 'MS']
>>> P.contents(clas=Mesh, func=lambda k, v: hasattr(v, 'inside'))
['MS']
>>> P.contents(like='M.*', sort='th')   # match anything starting with M
['MF', 'M2', 'M10', 'MS']
addfilter(fname, clas=None, like=None, func=None)[source]

Add a persistent filter

available_filters()[source]

List the available filters

filtered_items(func)[source]

Return items that pass a filter function

apply_filter(fname)[source]

Apply a named filter and remember result.

set_filter(fname=None, *, clas=None, like=None, func=None)[source]

Set the current Project filter

Parameters have the same meaning as in contents(). If any of clas, like or func is provided, fname is disregarded and a new filter is created under the name ‘_custom_’. Else, fname should be an existing filter name or None (which is equivalent to ‘all’).

filtered(fname=None, *, clas=None, like=None, func=None)[source]

Set the current filter and return a dict with filtered items

Returns:

dict – The items from the Project that pass the filter.

load(filename=None, **kargs)[source]

Load a project from file.

The objects loaded from the file update the current project.

Parameters:
  • filename (path_like) – The name of a file to load (.pzf, .pyf, .pyf.gz). If not provided, use the filename set in the Project. An exception is raised if neither is specified.

  • kargs – Keyword parameters to be passed to the PzfFile.load() or PyfFile.load() function.

Returns:

Path – On success, the Path of the loaded file.

save(filename=None, **kargs)[source]

Save the project to file.

Parameters:
  • filename (path_like) – The name of the file to save to (.pzf, .hdf5, .pyf, .pyf.gz). If not provided, the filename set in the Project is used. An exception is raised if neither is specified.

  • kargs – Keyword parameters to be passed to the PzfFile.save() or PyfFile.save() function.

close(clear=True)[source]

Detach the project from the project file

Parameters:

clear (bool) – If True (default) clears the filename attribute and the contents of the project dict. If False, the life contents is kept in memory.

pformat(header='Project contents:\n', keys=None)[source]

Pretty print (some) contents

pprint(*args, **kargs)[source]

Pretty print (some) contents

rename(oldname, newname)[source]

Rename an object.

Parameters:
  • oldname (str) – The old name of the object. A KeyError is raised if it is not in the Project.

  • newname (str) – The new name for the object self[newname]. A ValueError is raised if the name already exists.

Examples

>>> P = Project(data={'a':0, 'b':1})
>>> P.rename('b', 'c')
>>> dict(P)
{'a': 0, 'c': 1}
>>> P.rename('b', 'd')
Traceback (most recent call last):
...
KeyError: 'b'
>>> P.rename('c', 'a')
Traceback (most recent call last):
...
ValueError: The name 'a' already exists in the Project
forget(*names)[source]

Silently remove named objects from the Project.

Parameters:

*names (str) – One or more object names to be removed from the project. Removal is silent: non-existing names are silently skipped.

Examples

>>> P = Project(data={'a':0, 'b':1})
>>> P.forget('b', 'c')
>>> dict(P)
{'a': 0}
keep(*names)[source]

Forget everything except the specified names.

Parameters:

*names (str) – One or more names of objects to be kept in the project. Removal is silent: non-existing names are silently skipped.

Examples

>>> P = Project(data={'a':0, 'b':1})
>>> P.keep('a', 'd')
>>> dict(P)
{'a': 0}
update2(names, values)[source]

Update the Project from a list of names and a list of values

Parameters:
  • names (list of str) – A list of names to use as keys.

  • values (list of objects) – A list of objects to store in the project under the provided names.

Notes

This is syntactical sugar for self.update(zip(names, values)). If the lists have different lengths, the shorter one is used.

Examples

>>> P = Project(data={'a':0})
>>> P.update2(('b', 'c'), (1, 2))
>>> dict(P)
{'a': 0, 'b': 1, 'c': 2}
remember(names=None)[source]

Remember the current values of the variables in selection.

names: list or dict

rollback()[source]

Undo the last remembered changes

Examples

>>> P = Project(data=dict(a=0, b=1, c=2))
>>> P.remember(['a', 'c'])
>>> P['a'] = 5
>>> P['b'] = 6
>>> dict(P)
{'a': 5, 'b': 6, 'c': 2}
>>> P.rollback()
>>> dict(P)
{'a': 0, 'b': 6, 'c': 2}