Search code examples
pythonloopsunit-testingdictionaryattributeerror

I am trying test a function that sorts a nested array of dictionaries buy the key "createdAt" but coming across an attribute error


In short I am receiving a list of project_versions_items as a list of dictionaries, using the "CreatedAt" key to sort that list and compare that list to a delete_list (structured as a list of dic). The 6 oldest/createdAt will be appended to delete_list should the item not exist already.

I have checked vids and documentation and know I am on the right track with nested dictionaries but cant figure out now where I am going wrong

However, the error above keeps emerging and I am no exhausted of options- please help.

Error in terminal:

py::test__total_count_check Failed: \[undefined\]AttributeError: 'dict' object has no attribute 'sort'

TestCase:

`
def test__total_count_check():
input_project_items = load_json_fixture(
"fixtures/blackduck/api.project.createdAt.json"
)
input_delete_list = \[\]
expected_delete_list_ouput = \[\]
\# WHEN
populate_blackduck_delete_list = total_count_check(
input_project_items, input_delete_list
)
\# THEN
assert populate_blackduck_delete_list == expected_delete_list_ouput
`

An example of the 6 items in the expected_delete list array of dictionaries are as follows:

`
"items": \[
{
"versionName": "CICD-1264",
"phase": "DEVELOPMENT",
"distribution": "EXTERNAL",
"license": {
"type": "DISJUNCTIVE",
"licenses": \[
{
"license": "XYZ",
"licenses": \[\],
"name": "Unknown License",
"ownership": "UNKNOWN",
"licenseDisplay": "Unknown License",
"licenseFamilySummary": {
"name": "Unknown",
"href": "XYZ"
}
}
\],
"licenseDisplay": "Unknown License"
},
"createdAt": "2022-07-27T10:09:52.490Z",
"createdBy": "XYZ",
"createdByUser": "XYZ",
"settingUpdatedAt": "2022-07-27T10:09:52.490Z",
"settingUpdatedBy": "XYZ",
"settingUpdatedByUser": "XYZ",
"source": "CUSTOM",
"\_meta": {
"allow": \[
"DELETE",
"GET",
"PUT"
\],
`

and the original function as follows:

`
def total_count_check(project_version_items, delete_list):
project_version_items.sort(key=operator.itemgetter("createdAt"))
for item in project_version_items:
if item not in delete_list:
delete_list.append(item)
if len(delete_list) \>= 6:
break
return delete_list
`

project_version_items.sort(key=operator.itemgetter("createdAt")) I understand the error does not like sort yet in the various documentation this should be ok?


Solution

  • You have provided fragmentary data, so it's not totally clear, but I think you are passing in a dict (since it comes from a .json) with a key called "items". The value of the "items" key is a list. Presumably this list is sortable, however, you're applying the .sort() function to the dict. Apply it to the value of the "items" key instead.

    So, if I try to figure out what you're working with, it might look like this:

    import operator
    
    someDict = {
        "items": [
            {
                "versionName": "CICD-1264",
                "phase": "DEVELOPMENT",
                "distribution": "EXTERNAL",
                "license": {
                    "type": "DISJUNCTIVE",
                    "licenses": [
                        {
                            "license": "XYZ",
                            "licenses": [],
                            "name": "Unknown License",
                            "ownership": "UNKNOWN",
                            "licenseDisplay": "Unknown License",
                            "licenseFamilySummary": {
                                "name": "Unknown",
                                "href": "XYZ"
                            }
                        }
                    ],
                    "licenseDisplay": "Unknown License"
                },
                "createdAt": "2022-07-27T10:09:52.490Z",
                "createdBy": "XYZ",
                "createdByUser": "XYZ",
                "settingUpdatedAt": "2022-07-27T10:09:52.490Z",
                "settingUpdatedBy": "XYZ",
                "settingUpdatedByUser": "XYZ",
                "source": "CUSTOM",
                "_meta": {
                    "allow": [
                        "DELETE",
                        "GET",
                        "PUT"
                    ],
                }
            },
    {
                "versionName": "CICD-1264",
                "phase": "DEVELOPMENT",
                "distribution": "EXTERNAL",
                "license": {
                    "type": "DISJUNCTIVE",
                    "licenses": [
                        {
                            "license": "XYZ",
                            "licenses": [],
                            "name": "Unknown License",
                            "ownership": "UNKNOWN",
                            "licenseDisplay": "Unknown License",
                            "licenseFamilySummary": {
                                "name": "Unknown",
                                "href": "XYZ"
                            }
                        }
                    ],
                    "licenseDisplay": "Unknown License"
                },
                "createdAt": "2022-07-27T10:09:51.490Z",
                "createdBy": "XYZ",
                "createdByUser": "XYZ",
                "settingUpdatedAt": "2022-07-27T10:09:52.490Z",
                "settingUpdatedBy": "XYZ",
                "settingUpdatedByUser": "XYZ",
                "source": "CUSTOM",
                "_meta": {
                    "allow": [
                        "DELETE",
                        "GET",
                        "PUT"
                    ],
                }
            }        
        ]
    }
    
    someDict["items"].sort(key=operator.itemgetter("createdAt"))
    print(someDict)
    

    The output then looks like this:

    {'items': [{'versionName': 'CICD-1264', 'phase': 'DEVELOPMENT', 'distribution': 'EXTERNAL', 'license': {'type': 'DISJUNCTIVE', 'licenses': [{'license': 'XYZ', 'licenses': [], 'name': 'Unknown License', 'ownership': 'UNKNOWN', 'licenseDisplay': 'Unknown License', 'licenseFamilySummary': {'name': 'Unknown', 'href': 'XYZ'}}], 'licenseDisplay': 'Unknown License'}, 'createdAt': '2022-07-27T10:09:51.490Z', 'createdBy': 'XYZ', 'createdByUser': 'XYZ', 'settingUpdatedAt': '2022-07-27T10:09:52.490Z', 'settingUpdatedBy': 'XYZ', 'settingUpdatedByUser': 'XYZ', 'source': 'CUSTOM', '_meta': {'allow': ['DELETE', 'GET', 'PUT']}}, {'versionName': 'CICD-1264', 'phase': 'DEVELOPMENT', 'distribution': 'EXTERNAL', 'license': {'type': 'DISJUNCTIVE', 'licenses': [{'license': 'XYZ', 'licenses': [], 'name': 'Unknown License', 'ownership': 'UNKNOWN', 'licenseDisplay': 'Unknown License', 'licenseFamilySummary': {'name': 'Unknown', 'href': 'XYZ'}}], 'licenseDisplay': 'Unknown License'}, 'createdAt': '2022-07-27T10:09:52.490Z', 'createdBy': 'XYZ', 'createdByUser': 'XYZ', 'settingUpdatedAt': '2022-07-27T10:09:52.490Z', 'settingUpdatedBy': 'XYZ', 'settingUpdatedByUser': 'XYZ', 'source': 'CUSTOM', '_meta': {'allow': ['DELETE', 'GET', 'PUT']}}]}
    

    I constructed the modified dict such that the sort would have the effect of switching the first and second items, above, based on the value of the createdAt field.