0

I need to convert an xsd to a PostgreSQL schema, for which I found this Python script. Unfortunately it's a Python 2 script, so I want to convert it to Python 3. It fails on this part however:

parser.add_argument(
    'xsd', 
    metavar='FILE', 
    type=file,
    nargs='+',
    help='XSD file to base the Postgres Schema on'
)

The error says:

Traceback (most recent call last):
  File "xsd2pgsql.py", line 183, in <module>
    type=file, 
NameError: name 'file' is not defined

I know there's no type file any more in Python 3. How can I fix this?

1
  • You probably shouldn't have used file in Python 2, either. Use argparse.FileType instead. Commented Jun 13, 2020 at 14:47

2 Answers 2

1

The type argument will accept any callable which will take the string used on the command line and return some object of the desired type.

So in this case, just doing type=open would be equivalent to the action of type=file in Python 2, which is to return the handle of a file opened in read-only mode.

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('infile', type=file)
args = parser.parse_args()

print(args.infile.readline())

gives:

$ python2 test.py /etc/passwd
root:x:0:0:root:/root:/bin/bash

$ python3 test.py /etc/passwd
Traceback (most recent call last):
  File "test.py", line 5, in <module>
    parser.add_argument('filename', type=file)
NameError: name 'file' is not defined

After changing to type=open

$ python3 test.py /etc/passwd
root:x:0:0:root:/root:/bin/bash

(This will also work with python 2.)

However, a greater range of file opening options is available using argparse.FileType (see documentation).

This needs to be instantiated, so the basic usage is argparse.FileType(), but for example you could use argparse.FileType(mode="w") (or just argparse.FileType("w")) to get a file opened for writing. So this code:

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('outfile', type=argparse.FileType(mode="w"))
args = parser.parse_args()

args.outfile.write("hello\n")
args.outfile.close()

would give this:

$ python3 test.py myoutput
$ cat myoutput 
hello

although this would not be necessary for conversion of the Python 2 example in the question.

Sign up to request clarification or add additional context in comments.

Comments

1

argparse comes with a file wrapper that will open a file for you.

parser.add_argument(
    'xsd', 
    metavar='FILE', 
    type=argparse.FileType('r'),
    help='XSD file to base the Postgres Schema on'
)

This would have been preferred in Python 2 as well.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.