Combine argparse.MetavarTypeHelpFormatter, argparse.ArgumentDefaultsHelpFormatter and argparse.HelpFormatter

70 Views Asked by At

I want to display default values, argument type, and big spacing for --help.

But if I do

import argparse
class F(argparse.MetavarTypeHelpFormatter, argparse.ArgumentDefaultsHelpFormatter, lambda prog: argparse.HelpFormatter(prog, max_help_position = 52)): pass
parser = argparse.ArgumentParser(
    prog = 'junk', 
    formatter_class = F)

It gives the following error

TypeError: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases

Does anyone know how to combine these three formatters correctly?

2

There are 2 best solutions below

0
hpaulj On BEST ANSWER

Separating the lambda part works

In [122]: class F(argparse.MetavarTypeHelpFormatter, argparse.ArgumentDefaultsHelpFormatter): pass
     ...: F1 = lambda prog: F(prog, max_help_position=52)
     ...: parser = argparse.ArgumentParser(
     ...:     prog = 'junk', 
     ...:     formatter_class = F1)

In [123]: parser.print_help()
usage: junk [-h]

options:
  -h, --help  show this help message and exit

The lambda expression isn't used to make a new subclass, but to modify how the class is called.

In [136]: parser = argparse.ArgumentParser(
     ...:     prog = 'junk', 
     ...:     formatter_class = F1)
     ...: parser.add_argument('--long_name', type=float, default='123.213', help='help line');

In [137]: parser.print_help()
usage: junk [-h] [--long_name float]

options:
  -h, --help         show this help message and exit
  --long_name float  help line (default: 123.213)

On the argparse bug/issues board it has been suggested that you can subclass the helpformatter by inheriting from several of the provided subclasses. But no one has tested all combinations. The provided subclasses just modify one or more of the formatter methods to produce the desired change. You could make those changes directly in your class. Read the argparse.py code to see how

On using the lambda formatter:

Explain lambda argparse.HelpFormatter(prog, width)

I show how you can do by subclassing, but the lambda expression is simpler.

Also

where is the documentation for the python argparse helpformatter class?

0
J_H On

The same symptom is easily reproduced with a simpler setup.

>>> def identity(prog):
...     return prog
... 
>>> class F(object, identity): pass
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases

Cite your reference, please. I can't imagine why someone would believe that attempting to configure the MRO in that way would meet with success. Put the help formatter functionality into a class and inherit from that.

The thing you're trying to do is unsupported, and python is correctly providing a diagnostic which explains that.


Does anyone know how to combine these three formatters correctly?

A constructive way to engage with the SO community would be to implement some of the desired functionality, write a (passing) test suite that demonstrates that functionality, and then add a (failing) test describing the feature you're missing. Ask folks for help in implementing that feature. We won't have to guess about "what does 'correctly' mean?", since the unit test will describe precisely what it means.