[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[HTCondor-users] Some bugs and inconsistencies in the new Python bindings



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