Mara55789
Mara55789

Reputation: 19

Converting a Perl module to JSON with Python

I have a Perl (.pm) file that I've been trying to get into a JSON representation so that I can then search for keywords inside of it.

The directory for my script is /Devices/bin/script.py. The directory where the .pm file lives in one level up, so /Devices/Devices.PM. Devices.PM is just a static file containing data structured as dictionaries and lists like so:

mylist = (
    blah => {
        other       =9,
        houses       => 1,
        etc => [
            {   etc   => '5',
                ppl      => '3,
                things       => "etc",
                animals => [ 'blah-228', 'blah-229' ]
            },
            {   etc   => '9',
                ppl      => '5',
                things       => "22",
                animals => [ 'blah-2', 'blah-5' ]
            },
        ],
        partner => 'ets',
        location => 'wherever',
    },
    blah => {
        ppl => 6,
        place => 101,
        things => 'etc',
        animals => 'whatever',
    },

I have:

os.chdir("..")
with open('Devices.pm', 'r') as f:
    json_obj = json.dumps(f)
    print json_obj

but I keep getting TypeError: <open file 'SwitchConfig.pm', mode 'w' at 0x10c1f69c0> is not JSON serializable. I have tried this several ways with no luck, including json.dump(s). I keep getting different errors. Am I not understanding my .pm file structure correctly in order to turn it into a JSON representation?

Upvotes: 1

Views: 1308

Answers (2)

zdim
zdim

Reputation: 66883

It seems that you need to read this with a Perl script (or one-liner) and so export proper JSON.

First, what is shown is not valid Perl. I'll assume typos in posting for some basic syntax errors.

There is also a missing % in front of mylist; in Perl variable names start with a sigil, % for hashes. I'll assume that it is an omission in posting but that it is there. If not, you'd have to fix that.

Let me then use a file data.pm such as

%mylist = ( 
    blah => { 
        other  => 9, 
        houses => 1,
        etc    => [ { etc => '5', ppl => '3' }, { etc => '9', ppl => '5' } ]
    }
);

which is a short sample of posted data, with a few typos fixed.

Here is a Perl script to make JSON from it. It uses do to execute the file as a script, and thus read the data structure (hash) into the program. Then JSON::PP module is used to make JSON out of it, since it should be installed on a system with Perl.

use warnings;
use strict;
use JSON::PP;

my %data = do './data.pm';

my $data_json = encode_json \%data;

print $data_json, "\n";  # just to see it

my $outfile = 'data.json';
open my $fh, '>', $outfile or die "Can't open $outfile: $!";
print $fh $data_json, "\n";
close $fh;

The whole job is done in the first two lines. The JSON::PP is a core module (since v5.14) but if an external dependency isn't a problem use JSON, which uses the fast JSON::XS if installed.

This nicely fits in a one-liner

perl -MJSON::PP -wE'say encode_json { do "./data.pm" }' > data.json

where the output is redirected to the file.

Both the program and the one-liner output (broken over lines for readability)

{"blah":{"other":"9","houses":"1","etc":
    [{"ppl":"3","etc":"5"},{"ppl":"5","etc":"9"}]}}

what is the content of the file data.json which is written.

For this to work the .pm file has to contain only a valid Perl data structure. If there is more variables than that one hash this won't work, since do doesn't return all that data. Then you'd have to process the file by other means.

Upvotes: 4

jwodder
jwodder

Reputation: 57480

json.dumps converts from a Python object (like {"foo": True}) to a string representing that object as JSON (like '{"foo": true}'). You appear to be trying to go the other way and convert a file containing JSON to a Python object; the function that does this is json.load. However, that still won't work, as Devices.pm does not contain JSON. You'll need to either write a Perl script that imports Devices.pm and then dumps its contents as actual JSON or else write a parser for Perl in Python. I recommend the first approach.

Upvotes: 0

Related Questions