Re: Custom sort order for YAML output

Sam Kuper <[email protected]>
Newsgroups gmane.text.yaml.general
Message-ID <[email protected]>
2009/9/22 Markus Jarderot <[email protected]>

>  [BEGIN]
>
> import yaml
>
> def represent_dict(self, data):
>     def key_function((key,value)):
>         # Prioritizes certain keys when sorting.
>         prio = {"model":0,"pk":1,"fields":2}.get(key,99)
>         return (prio, key)
>     items = data.items()
>     items.sort(key=key_function)
>     return self.represent_mapping(u'tag:yaml.org,2002:map', items)
>
> yaml.add_representer(represent_dict)
>
> [END]
>

Thank you for the suggestion. It doesn't quite work as it stands, but it got
me most of the way there and I figured out the last step with a little trial
and error. I'll explain. Suppose I do the following:

[BEGIN]
from optparse import OptionParser
import yaml

def represent_dict(self, data):
    def key_function((key,value)):
        # Prioritizes certain keys when sorting.
        prio = {"model":0,"pk":1,"fields":2}.get(key,99)
        return (prio, key)
    items = data.items()
    items.sort(key=key_function)
    return self.represent_mapping(u'tag:yaml.org,2002:map', items)

yaml.add_representer(represent_dict)

def main():
    # set up optparse
    usage = "usage: %prog [options] INPUT\nReads yaml from INPUT and returns
it as block style yaml to stdout"
    parser = OptionParser(usage)
    (options, args) = parser.parse_args()
    if len(args) != 1:
        parser.error("incorrect number of arguments")

    # get some flow style YAML from FILE1
    try:
        infile = open(args[0])
    except IOError:
        print 'Cannot open input file: ', args[0]
    else:
        input = infile.read()
        output = yaml.dump(yaml.load(input), default_flow_style=False)
        print output

# execute main()
if __name__ == "__main__":
    main()
[END]

Running: python yaml_to_block_style.py fixtures/dumped_data.yaml
yields:

Traceback (most recent call last):
  File "yaml_to_block_style.py", line 13, in <module>
    yaml.add_representer(represent_dict)
TypeError: add_representer() takes at least 2 arguments (1 given)


It seems that the first argument to add_representer should be a class name.
At first I thought that's not really appropriate in my case because I'm not
trying to represent a class (at least, not a class that's defined in my
code). Then I tried writing the add_representer line as:

yaml.add_representer(str, represent_dict)

since str is the class name of *input*, but this just yields:

Traceback (most recent call last):
  File "yaml_to_block_style.py", line 35, in <module>
    main()
  File "yaml_to_block_style.py", line 30, in main
    output = yaml.dump(yaml.load(input), default_flow_style=False)
  File "/home/me/django001/__init__.py", line 175, in dump

  File "/home/me/django001/__init__.py", line 165, in dump_all

  File "build/bdist.linux-i686/egg/yaml/representer.py", line 33, in
represent
  File "build/bdist.linux-i686/egg/yaml/representer.py", line 62, in
represent_data
  File "build/bdist.linux-i686/egg/yaml/representer.py", line 220, in
represent_list
  File "build/bdist.linux-i686/egg/yaml/representer.py", line 106, in
represent_sequence
  File "build/bdist.linux-i686/egg/yaml/representer.py", line 62, in
represent_data
  File "build/bdist.linux-i686/egg/yaml/representer.py", line 228, in
represent_dict
  File "build/bdist.linux-i686/egg/yaml/representer.py", line 127, in
represent_mapping
  File "build/bdist.linux-i686/egg/yaml/representer.py", line 62, in
represent_data
  File "yaml_to_block_style.py", line 9, in represent_dict
    items = data.items()
AttributeError: 'str' object has no attribute 'items'

shell returned 1


Finally, I tried changing the line to:

yaml.add_representer(dict, represent_dict)

And this worked!

Thank you,

Sam


> Sam Kuper skrev:
>
> Dear list,
>
> Bearing in mind I'm new to PyYAML, please could you help with the
> following.
>
> I'm using PyYAML to convert dumped YAML data from Django (which is flow
> style by default) into block style via the following Python script:
>
> [BEGIN]...[END]
>
> This works, but I'd like to output the data in the order shown here<http://docs.djangoproject.com/en/dev/howto/initial-data/#providing-initial-data-with-fixtures>- in other words, in the form:
>
> - model:
>   pk:
>   fields:
>
> I'd also like the fields to be sorted alphabetically.
>
> This ticket <http://pyyaml.org/ticket/23> suggests to me that this should
> be possible, but I'm not sure how best to insert a "custom representer"into the script above, in order to get the result I'm seeking.
>
> I'd be grateful for any help you can offer.
>
> Many thanks in advance,
>
> Sam
>
>

------------------------------------------------------------------------------
Come build with us! The BlackBerry&reg; Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay 
ahead of the curve. Join us from November 9&#45;12, 2009. Register now&#33;
http://p.sf.net/sfu/devconf

_______________________________________________
Yaml-core mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/yaml-core
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.