Skip to content

Commit c08a0f8

Browse files
committed
Updated README.
1 parent 2f40f17 commit c08a0f8

File tree

1 file changed

+87
-7
lines changed

1 file changed

+87
-7
lines changed

README.md

Lines changed: 87 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
Xaux is a package with support tools, both for general usage and tune for CERN / Xsuite usage. It is thoroughly tested for all python versions from 3.8 onwards, to ensure stability. The following tools are provided:
44

5+
56
### Singleton
67
The decorator `@singleton` will redefine a class into a singleton such that only one instance exists and the same instance is returned every time the class is instantiated.
78

@@ -11,6 +12,30 @@ The decorator `@singleton` will redefine a class into a singleton such that only
1112
- The singleton can be reset by calling the `delete()` method of the class, which will invalidate any existing instances.
1213
- The decorator provides a `get_self()` method, which is a class method that is more relaxed than the constructor, as it allows passing any `**kwargs` even if they aren't attributes for the singleton (these will then just be ignored). This is useful for kwargs filtering in getters or specific functions.
1314

15+
Example usage:
16+
17+
```python
18+
@singleton
19+
class MyClass:
20+
21+
def __init__(self, value=10):
22+
self.value = value
23+
```
24+
```python
25+
>>> instance1 = MyClass(value=8)
26+
>>> instance2 = MyClass(value=9)
27+
>>> print(instance1.value)
28+
9
29+
>>> print(instance2.value)
30+
9
31+
>>> print(instance1 is instance2)
32+
True
33+
>>> instance3 = MyClass()
34+
>>> print(instance1.value)
35+
9
36+
```
37+
38+
1439
### Class Property
1540
The descriptor `@ClassProperty` works similar as `@property` but is used to define class properties (instead of instance properties).
1641

@@ -29,16 +54,35 @@ class MyClass(metaclass=ClassPropertyMeta):
2954

3055
@ClassProperty
3156
def my_class_property(cls):
57+
print("In getter")
3258
return cls._my_classproperty
3359

3460
@my_class_property.setter
3561
def my_class_property(cls, value):
62+
print("In setter")
3663
cls._my_classproperty = value
3764

3865
@my_class_property.deleter
3966
def my_class_property(cls):
67+
print("In deleter")
4068
cls._my_classproperty = 0
4169
```
70+
```python
71+
>>> print(MyClass.my_class_property)
72+
In getter
73+
0
74+
>>> MyClass.my_class_property = 3
75+
In setter
76+
>>> print(MyClass.my_class_property)
77+
In getter
78+
3
79+
>>> del MyClass.my_class_property
80+
In deleter
81+
>>> print(MyClass.my_class_property)
82+
In getter
83+
0
84+
```
85+
4286

4387
### FsPath
4488
This is an extension to the `Path` class from `pathlib`, which is adapted to work, besides on regular local file systems, robustly and efficiently on AFS (the Andrew File System) and EOS (a storage-oriented file system developed at CERN). It defines three classes, `LocalPath`, `AfsPath`, and `EosPath`, and a class factory `FsPath`. The correct class will be automatically instantiated based on the file system on which the path sits. Care is taken to correctly resolve a path when symlinks are present.
@@ -47,14 +91,27 @@ The main advantage is that for a whole set of file operations, the standard `Pat
4791

4892
Note that `LocalPath` is just a regular `Path` but with additional access to the `FsPath` methods.
4993

50-
### General Tools
51-
These are a set of lightweight tools:
52-
- `timestamp` provides an easy way to get timestamps into logs and filenames (with second, millisecond, or microsecond accuracy).
53-
- `ranID` generates a Base64 encoded random ID string, useful for in filenames or element names.
54-
- `system_lock` is typically used for a cronjob. It will exit the python process if the previous cronjob did not yet finish (based on a custom lockfile name).
55-
- `get_hash` is a quick way to hash a file, in chunks of a given size.
94+
Example usage:
95+
96+
```python
97+
>>> path = FsPath('/newhome/fvanderv/work') # 'work' is a symbolic link on a local file system that points to an AFS folder
98+
>>> path
99+
LocalPosixPath('/newhome/fvanderv/work')
100+
>>> path.resolve()
101+
AfsPosixPath('/afs/cern.ch/work/f/fvanderv')
102+
```
103+
```python
104+
>>> path = FsPath('/eos/project/c/collimation-team')
105+
>>> path
106+
EosPosixPath('/eos/project/c/collimation-team')
107+
>>> path.eos_path # EosPath objects have a few specific attributes that correctly resolve EOS components
108+
/eos/project/c/collimation-team
109+
>>> path.eos_path_full
110+
root://eosproject.cern.ch//eos/project/c/collimation-team
111+
>>> path.eos_instance
112+
project
113+
```
56114

57-
Then there are also a few tools to get info about a function's arguments, which are only accessible via `xaux.tools` and are essentially just wrappers around functions in `inspect`. These are `count_arguments`, `count_required_arguments`, `count_optional_arguments`, `has_variable_length_arguments`, `has_variable_length_positional_arguments`, and `has_variable_length_keyword_arguments`.
58115

59116
### ProtectFile
60117
This is a wrapper around a file pointer, protecting it with a lockfile. It is meant to be used inside a context, where the entering and leaving of a context ensures file protection. The moment the object is instantiated, a lockfile is generated (which is destroyed after leaving the context). Attempts to access the file will be postponed as long as a lockfile exists. Furthermore, while in the context, file operations are done on a temporary file, that is only moved back when leaving the context.
@@ -65,6 +122,29 @@ Several systems are in place to (almost) completely rule out concurrency and rac
65122

66123
The tool works particularly well on EOS using the FsPath mechanics, however, on AFS it cannot be used reliably as different node servers can be out-of-sync with each other for a few seconds up to minutes.
67124

125+
Example usage:
126+
127+
```python
128+
import json
129+
from xaux import ProtectFile
130+
with ProtectFile(info.json, 'r+', wait=1) as pf:
131+
meta = json.load(pf)
132+
meta.update({'author': 'Emperor Claudius'})
133+
pf.truncate(0) # Delete file contents (to avoid appending)
134+
pf.seek(0) # Move file pointer to start of file
135+
json.dump(meta, pf, indent=2, sort_keys=False))
136+
```
137+
138+
### General Tools
139+
These are a set of lightweight tools:
140+
- `timestamp` provides an easy way to get timestamps into logs and filenames (with second, millisecond, or microsecond accuracy).
141+
- `ranID` generates a Base64 encoded random ID string, useful for in filenames or element names.
142+
- `system_lock` is typically used for a cronjob. It will exit the python process if the previous cronjob did not yet finish (based on a custom lockfile name).
143+
- `get_hash` is a quick way to hash a file, in chunks of a given size.
144+
145+
Then there are also a few tools to get info about a function's arguments, which are only accessible via `xaux.tools` and are essentially just wrappers around functions in `inspect`. These are `count_arguments`, `count_required_arguments`, `count_optional_arguments`, `has_variable_length_arguments`, `has_variable_length_positional_arguments`, and `has_variable_length_keyword_arguments`.
146+
147+
68148
### Dev Tools for Xsuite
69149
These are tools used for the maintenance and deployment of python packages. They are not in the test suite, and only accessible via `xaux.dev_tools`. The low-level functionality is a set of wrappers around `gh` (GitHub CLI), `git`, and `poetry`, while the higher-level functions are `make_release`, `make_release_branch`, `rename_release_branch` which are tailored to Xsuite and go through the same sequence of steps (verifying the release version number, making a PR to main, accepting it, publishing to PyPi, and making draft release notes on GitHub), while asserting the local workspace is clean and asking confirmation at each step. These are currently used as the default tools to maintain and deploy `xaux`, `xboinc`, `xcoll`, and `xdyna`.
70150

0 commit comments

Comments
 (0)