Assigning assigned_object to None doesn't work unless it's referenced
pynetbox version
v7.5.0
NetBox version
v4.3.7
Python version
3.12
Steps to Reproduce
mac_address = nb.dcim.mac_addresses.get(id=30180)
interface = mac_address.assigned_object
# Uncommenting this gets it working as expected
# print(interface.primary_mac_address)
interface.primary_mac_address = None
print(interface.save())
Expected Behavior
I expected the primary mac address to be unset
Observed Behavior
The primary mac address was still set.
@aj2s This works fine for me, the primary Mac addresss was reset checked in both API and UI. Can you please double-check.
mac_address = nb.dcim.mac_addresses.get(id=1)
print(mac_address)
interface = mac_address.assigned_object
print(interface.primary_mac_address)
interface.primary_mac_address = None
interface.save()
mac_address = nb.dcim.mac_addresses.get(id=1)
interface = mac_address.assigned_object
print(interface.primary_mac_address)
Thanks for the quick triage! That does work, but that's only because there's the call to print(interface.primary_mac_address) on line 4. It does not work for me when I *do not print / reference interface.primary_mac_address anywhere.
Is that expected? If so, it's not intuitive to me.
Here's an updated snippet with the line in question separated out for clarity
nb = pynetbox.api(os.environ["NETBOX_URL"], os.environ["NETBOX_TOKEN"])
mac_address = nb.dcim.mac_addresses.get(id=MAC_ADDRESS_ID)
interface = mac_address.assigned_object
# Commenting this out / not referencing interface.primary_mac_address causes this snippet to not update interface.primary_mac_address on interface.save()
print("primary mac before", interface.primary_mac_address)
interface.primary_mac_address = None
interface.save()
mac_address = nb.dcim.mac_addresses.get(id=MAC_ADDRESS_ID)
interface = mac_address.assigned_object
print("primary mac after", interface.primary_mac_address)
I have confirmed the call to save() is not triggering any network request. From what I understand, that means that the call to _diff detects no change, right? I'm interested in deepening my understanding of how pynetbox works internally, but that will not be this week :)
Script:
import os
import pynetbox
import logging
MAC_ADDRESS_ID = 30180
logger = logging.getLogger(__name__)
logging.basicConfig(level=logging.DEBUG, format="%(levelname)s: %(message)s")
nb = pynetbox.api(os.environ["NETBOX_URL"], os.environ["NETBOX_TOKEN"])
mac_address = nb.dcim.mac_addresses.get(id=MAC_ADDRESS_ID)
interface = mac_address.assigned_object
logging.info("Setting primary_mac_address to None")
interface.primary_mac_address = None
logging.info("Saving")
interface.save()
logging.info("Supposedly saved")
mac_address = nb.dcim.mac_addresses.get(id=MAC_ADDRESS_ID)
interface = mac_address.assigned_object
logging.info("primary mac after: %s", interface.primary_mac_address)
Output (with redacted domain):
DEBUG: Starting new HTTPS connection (1): netbox.example.com:443
DEBUG: https://netbox.example.com:443 "GET /api/dcim/mac-addresses/?id=30180&limit=0 HTTP/1.1" 200 923
INFO: Setting primary_mac_address to None
INFO: Saving
INFO: Supposedly saved
DEBUG: https://netbox.example.com:443 "GET /api/dcim/mac-addresses/?id=30180&limit=0 HTTP/1.1" 200 923
DEBUG: https://netbox.example.com:443 "GET /api/dcim/interfaces/24648/ HTTP/1.1" 200 797
DEBUG: https://netbox.example.com:443 "GET /api/dcim/mac-addresses/30180/ HTTP/1.1" 200 871
INFO: primary mac after: 8C:1F:64:05:5D:BF
Does look like the print is causing it to be de-reffed and makes it work. Adding to backlog for more investigation as it does not seem correct.
Leaving a fix here: https://github.com/netbox-community/pynetbox/compare/master...NeverBehave:pynetbox:nb/test-1?expand=1
It is mostly caused by new fields not properly tracked if API does not return it in the first place AFAIK. Not sure if it is the best way to handle this situation.
@NeverBehave, would you like to take ownership of this one?
@NeverBehave, would you like to take ownership of this one?
You can assign me on this since I already have a working branch.