The only issue I can see with your code is that you are passing the field object to the AlterField tool, not the field name. Also, just FYI though it doesn't matter, you don't need to pass empty optional arguments to python functions. Change to:
arcpy.AlterField_management(fc, field.name, field.name.upper())
Alternatively, because tools generally use a field's name as input, it's often more useful to make a list of field names, not field objects. This is easy to do with list comprehension:
fieldList = [f.name for f in arcpy.ListFields(fc)]
for field in fieldList:
arcpy.AlterField_management(fc, field, field.upper())
A little more info: This should help you understand what I mean when I say "field object". When you use ListFields, the list you get is full of fields as explained in that documentation. Each of those field objects has a number of properties, which you access by referencing them like this: field.propertyname. The list comprehension above could be interpreted like this: "This new list will contain the .name property of all the objects (f
in this case) that are returned by the ListFields function," if that makes any sense. Or, a longer code version of same the operation could look like this:
fieldList = [] #make an empty list
for f in arcpy.ListFields(fc): #iterate through all of the field objects
fieldList.append(f.name) #append the name property of each object to the list
Finally, please look at @DWynne's answer.