Please help me debug this error

Please help me debug the error below.
Thanks.

traceback (most recent call last):
File “changemac.py”, line 23, in
change_mac(options.interface, options.new_mac)
AttributeError: Values instance has no attribute ‘new_mac’

Below is my code

#!/usr/bin/env python

import subprocess
import optparse

def change_mac(interface, new_mac):
print("[+] changing mac address for" + interface + “to” + new_mac)

subprocess.call(["ifconfig", interface, "down"])
subprocess.call(["ifconfig", interface, "hw", "either", new_mac])
subprocess.call(["ifconfig", interface, "up"])

parser = optparse.OptionParser()

parser.add_option("-i", “–interface”, dest = “interface”, help=“interface to change its mac address”)
parser.add_option("-m", “–mac”, help=“new mac address”)

(options, arguments) = parser.parse_args()

change_mac(options.interface, options.new_mac)

I’ve reformatted your code for you:

#!/usr/bin/env python

import subprocess
import optparse

def change_mac(interface, new_mac):
    print("[+] changing mac address for" + interface + "to" + new_mac)

subprocess.call(["ifconfig", interface, "down"])
subprocess.call(["ifconfig", interface, "hw", "either", new_mac])
subprocess.call(["ifconfig", interface, "up"])

parser = optparse.OptionParser()

parser.add_option("-i", "–interface", dest = "interface", help="interface to change its mac address")
parser.add_option("-m", "–mac", help="new mac address")

(options, arguments) = parser.parse_args()

change_mac(options.interface, options.new_mac)

… which makes it a little easier to see what’s going on.

Line 9: subprocess.call(["ifconfig", interface, "down"])
interface has not been defined at this point in your code.

edit: If, by doing that, I messed up the code blocks, please re-post, like this:

```python
your code goes here
```

Or you can use the </> option on the edit menu.

You define the variable “options” with this line:

(options, arguments) = parser.parse_args()

The options variable will be populated from the options you give on the command line, but you only define two possible options:

(1) The -i or --interface option, which gets stored as options.interface.

(By the way, I don’t think you need the dest="interface" argument, as optparse will default to “interface” as the destination.)

(2) The -m or --mac option, which gets stored as options.mac.

But you then ask for options.new_mac, and there is no such option as “new_mac”. So you get an error.

To fix this, you can do one of these three (untested) fixes:

(1) Either change this line:

change_mac(options.interface, options.new_mac)

to this:

change_mac(options.interface, options.mac)

(2) Or instead, change the name of the option:

parser.add_option("-m", "--mac", help="new mac address")

becomes this:

parser.add_option("-m", "--new-mac", help="new mac address")

(3) Or you can change the destination:

parser.add_option("-m", "--mac", help="new mac address")

becomes this:

parser.add_option("-m", "--mac", dest="new_mac", help="new mac address")

Warning: I am not an expert on optparse, and I have not tested any of these fixes. You will have to try them yourself and see if they work.

Good luck!

Thanks to you all, I’m grateful

Also, note that on many machines, #!/usr/bin/env python will run the obsolete Python 2, not Python 3. Make sure to use #!/usr/bin/env python3 as your shebang to avoid this. Also, note that for new/modern code, optparse has long been superseded by argparse, and subprocess.call by subprocess.run.

1 Like

Thanks.

I did, in fact, simply C&P the code that @Alpha1 posted, putting all the code between the Mardown backtics, as the OP had not done so.

It could be that his intention is to run this under Python 2.7, but we’ll need the OP’s input on that one.

I’ve seen a few posts (not that I’ve seen any in this Forum yet) of code that has been lifted from the book “Black Hat Python” by Justin Seitz, which, as I’m sure you’re aware, was written using Python 2.7, where the person asking the question, has simply replaced sections of said code using Python 3.6 syntax, then gets confused when the code fails to run as expected. I’m not saying that this is the case here, but the fact that the shebang is how it is and that things such as optparse and subprocess are being used, does make me believe that it’s the intention of the OP to run this under 2.7

My apologies; I meant to quote the OP rather than you, but wasn’t paying careful attention, and didn’t mean to imply that you had made an active mistake there, sorry.

To note, argparse is present in Python 2.7, which itself is well over a decade old and is the minimum version of Python in any still-supported system. If the user is still using Python 2.7, they do so at their own risk as it is EoL for well over a year and unsupported by the Python team and most of the community.

To note, even veteran users like @steven.daprano are largely unfamiliar with optparse these days, and in fact I myself have never seriously developed on Python 2 at all, having adopted Python six months after the release of 3.6 and at the point when Python 3 had started to become dominant for new development, at least in the scientific community. So even if we wanted to provide support for an obsolete version of the language, it would be difficult for most folks on here to do so.

That’s quite alright; these things happen. Thank you for clearing that up.

I’m in a very similar position, having discovered Python at the point where V3 was superseding V2 and it was real confusing for me at that time, as most of the content that I found (while searching for tutorials) were all about V2.7

The best advice that I could think of (while I was involved with another Forum much later on) was to tell OPs that if they wanted to use code that was developed in a 2.7 environment, then don’t try to adapted it: simply use a 2.7 environment in which to run the code.

Have a good day.

Interesting; I thought you’d mentioned before that you were still a relative beginner?

For what its worth, I would generally tend to give rather different advice. Nowadays, Python 3 has superseded Python 2 in both actual usage and, even more so, up to date tutorials, guides, how-tos and other educational materials for quite some time now, and there are plenty of such available.

Therefore, if users (particularly newer ones) are still relying on resources that are Python 2-only, such are likely both unmaintained and out of date relative to modern Python code, and thus they should find another more up to date resource, as much of the specifics they will be learning will have changed (particularly actual code), and they are likely to become very confused once they try to use Python in the real world and find out what they learned doesn’t work anymore.

And if they are going to be working with legacy Python 2 code, learning how to port it to Python 3 is a critical skill that they should learn fairly early on, once they have learned enough to be qualified to maintain such code in the first place.

I do class myself as a “relative beginner” when I see the skills of frequent posters in this Forum, but as you say, it’s ‘relative’.

I’ve been away from coding for the past 2 years or so (ill health), but I’m now trying to pick up from where I left off: it’s the old adage of ‘use it or lose it’.

The Forum in which I was involved, attracted more ‘script kiddies’ than seasoned coders and as such, learning how to port from P2 to P3, was of little interest to them; that aside, I could not agree more with what you say.

optparse is still available for Python 3.10, and likely will be for many more years to come.

There is no reason to take the use of optparse or subprocess as signs that the original poster is using Python 2.7; even the use of “python” rather than “python3” in the shebang line is not strong evidence.

I’m very sure that your knowledge is vastly superior to mine on this topic, as well as many others and I always look forward to reading your posts, as I know that I will learn something from what you have to say.

Please note that is was @CAM-Gerlach that said:

… and like you, his knowledge is superior to mine.

I think we need to hear from @Alpha1 on the subject of which version of Python the script is supposed to run under. That said, I take your point.

Thank you.

Yes, but I didn’t say that the OP’s intention was to run under Python 2 or 3 :slight_smile:
I just mentioned that the shebang was ambiguous and would run Python 2 on many machines, and that optparse and subprocess.run have more modern replacements, which are all statements of fact independent of whether the OP may or may not be intending to use an obsolete, unsupported interpreter version. I also later mentioned that argparse works just fine on Python 2 (at least any version that might still be in use)

To note, @steven.daprano 's knowledge and experience is certainly much superior to mine.

Well, I’m not sure how much difference that makes at this point. They’ve apparently solved their primary problem, and the points above stand regardless of their intended target version—the python shebang is ambiguous and may refer to Python 2, Python 3 or nothing depending on their OS and configuration, and if it refers to Python 2, that version is obsolete; argparse supersedes optparse, including in Python 2; and subprocess.run is a more capable replacement for subprocess.call for all supported Python versions.

Yes; it’s a confused situation. What adds more confusion (for me, least ways) is why is…

… if…

Should optparse not have been deprecated by now?


Edit to add: I’ve looked at both the documentation as well as the source code, but for me, that raises more questions than it answers.

Still, let’s put this to bed now as it’s become more of an academic exercise than a practical one and I’m sure we’ve all spent more than enough time on this.

My thanks to you both.

Peace.

See its section in the just-accepted PEP 594. However, its usage in all code on GitHub is now <10% of argparse’s, a point which I made when the PEP was updated, likely much less than when the PEP was originally written, so eventually it likely will be removed, but it isn’t yet.

optparse is deprecated. But removing it will break code that currently works fine, and for no good reason.

Yes, thanks. I did see that this was deprecated some time ago. What I meant was that I found it a little surprising that it found its way into P3 [thus not deprecated from P3], given that argparse was already established. I guess the answer to that is ‘backward compatibility’.

Indeed, the reasons optparse is not yet removed are detailed in
PEP 594 – Removing dead batteries from the standard library | peps.python.org but the summary from the Rationale
section is: “The optparse and getopt modules are widely used. They
are mature modules with very low maintenance overhead.”