Hi all,
As part of our migration to HTC25, Iâve been porting a wad of code from `htcondor` to `htcondor2` Python bindings. There are a few bugs and inconsistencies that I havenât seen reported here, so thought Iâd share them.
Sorry for the German negativity. The new bindings are actually a nice step up from the old design. ;)
Cheers,
Max
Bugs:
- Passing either tuple or list to `htcondor2.Collector` as `pool` doesn't work as the internal type check is wrong: (it should say `isinstance(pool, (list, tuple))`)
```
>>> htcondor2.Collector(('htcondor-lrms-1', 'htcondor-lrms-2'))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib64/python3.9/site-packages/htcondor2/_collector.py", line 65, in __init__
if isinstance(pool, [list, tuple]):
TypeError: isinstance() arg 2 must be a type or tuple of types
```
- `RecursionError` for anything needing `len(htcondor2.param)` (e.g. `list(htcondor2.param.keys())`) since the `KeysView` delegates back to the mapping and vice versa.
```
>>> len(htcondor2.param)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib64/python3.9/site-packages/htcondor2/_param.py", line 43, in __len__
return len(self.keys())
File "/usr/lib64/python3.9/_collections_abc.py", line 806, in __len__
return len(self._mapping)
File "/usr/lib64/python3.9/site-packages/htcondor2/_param.py", line 43, in __len__
return len(self.keys())
â
File "/usr/lib64/python3.9/site-packages/htcondor2/_param.py", line 43, in __len__
return len(self.keys())
File "/usr/lib64/python3.9/_collections_abc.py", line 806, in __len__
return len(self._mapping)
File "/usr/lib64/python3.9/site-packages/htcondor2/_param.py", line 43, in __len__
return len(self.keys())
File "/usr/lib64/python3.9/_collections_abc.py", line 777, in keys
return KeysView(self)
RecursionError: maximum recursion depth exceeded while calling a Python object
```
Documentation Inconsistencies:
- Typehint for `htcondor2.Collector` `pool` arguments includes `Tuple[str]` (a tuple with exactly one string) but should say `Tuple[str, ...]` (a tuple with any number of strings).
- The docs for `classad2.ClassAd` say
Expressions are always evaluated before being returned, and unless you call lookup(), converted into the corresponding Python type.
Yet using `classad[key]` access seems to only evaluate constant literal expressions, not general expressions.
```
>>> type(classad2.ExprTree('2'))
<class 'classad2._expr_tree.ExprTreeâ>
>>> type(classad2.ClassAd({'a': classad2.ExprTree('2')})['a'])
<class 'int'>
>>> type(classad2.ClassAd({'a': classad2.ExprTree('2+2')})['a'])
<class 'classad2._expr_tree.ExprTree'>
>>> type(classad2.ClassAd({'a': classad2.ExprTree('2+2')})['a'].eval())
<class 'int'>
```
- `classad2.ClassAd.matches` is explicitly documented to only check for a `True` return value, but also accepts non-zero int and float.
Some Inconsistencies with expectations from Python:
- Misleading `ClassAd.printJson` and `ClassAd.printOld` method names â they donât `print` but merely format. I understand thatâs the name in C source, but `ClassAd.formatJson` and `ClassAd.formatOld` aliases or similar would be nice for code clarity.
- Several enums are `enum.IntEnum` but have power-of-two values and are intended for bitwise combinations. Python's `enum.IntFlag` is more appropriate for that.
- `htcondor2.QueryOpt` and `htcondor2.TransactionFlag` seem to match this exactly
- `htcondor2.LogLevel` can be combined using bitwise-or according to `htcondor2.log`, but its member values are not power-of-two (e.g. `htcondor2.LogLevel.Error | htcondor2.LogLevel.Job == htcondor2.LogLevel.Machine`)
Attachment:
smime.p7s
Description: S/MIME cryptographic signature