1

Having issues with a recursive function that should be relatively simple to do, but can`t seem to get right.

I have a folder structure with folders that can contain other folders, images or files. Associated with each folder there are permissions. I want to have my function recursively build a list of the permissions that are associated with each folder.

I have a function has_read_permission(request) that returns True if the folder has permissions and False if not

I have built a function like so:

def get_child_perms(self, folder, request, perm_list):
        # Folder contains other folders
        if folder.get_children():
            # For every sub-folder
            for subfolder in folder.get_children():
                return perm_list.append(self.get_child_perms(subfolder, request, perm_list))
        else:
            # If folder doesn't have sub-folders containing folders
            return [folder.has_read_permission(request)]

I keep getting None

Given folders like so:

Folder (allowed) - Wont check this one
|_First Folder (allowed)
| |_First sub Folder (restricted)
| | |_File
| | |_File
| | |_Image
| |__Second Sub Folder (allowed)
|_Second Folder (allowed)

Then running get_child_perms() would return [True,False,True,True] or even [True, [False, True], True]

EDIT

Disregard edit -> asked other question Python Recursive function missing results

Changed abit,

def get_child_perms(self, folder, request, perm_list):
        if folder.get_children():
            for subfolder in folder.get_children():
                perm_list.append(self.get_child_perms(subfolder, request, perm_list))
            return perm_list
        else:
            return [folder.has_read_permission(request)]

getting:

[[True], [...], [True], [...], [...], [True], [True], [True], [True], [True], [True], [True], [True], [...], [True], [...]]

 Admin
 -Folder 1
   - Files
 -Folder 2
   - Files
 -Folder 3
   - Files 
 -Folder 4
   - SubFolder 1
      -SubSubFolder 1
         - Files
      - Files
   - SubFolder 2
      - SubSubFolder 2
           - Files
      - Files
 -Folder 5
   - SubFolder 3
       - Files
   - SubFolder 4
       - Files
   - SubFolder 5
       -Files
   - Files
 -Folder 6
   - Files
 -Folder 7
   - SubFoler 6
       - Files
   - Files
 -Folder 8
   - Files
4
  • Try to answer this question, will the for loop's body be executed if folder.get_children() returns and empty iterable? Commented Aug 19, 2015 at 17:58
  • 2
    Are you sure you want to return inside the loop? That will make it exit after at most one iteration. Commented Aug 19, 2015 at 18:00
  • Ya removed that return in loop Commented Aug 19, 2015 at 18:09
  • I don't understand your latest edit. If someone here solved your problem (i.e., you are no longer getting None), you should mark an answer accepted. Ask a new question if you have one, but you can't just keep editing this one until the function works just how you want it. Commented Aug 19, 2015 at 18:21

3 Answers 3

4
for subfolder in folder.get_children():
    perm_list.append(self.get_child_perms(subfolder, request, perm_list))
return perm_list

.append is in place. It does not return anything.So you are getting None

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

Comments

3

In-place list methods return None to remind you that they operate in place.

Instead of:

return permlist.append(self.get_child_perms(...  # etc.

Try:

permlist.append(self.get_child_perms(...
return permlist

Edited to add: As other comments/answers have pointed out, you'll want to return outside your for loop if you want it to complete.

Comments

1

As pointed out append is an inplace operation that returns None, you can avoid using append at all by returning a list comp:

def get_child_perms(self, folder, request, perm_list):
    # Folder contains other folders
    children =  folder.get_children()
    if children:
        # For every sub-folder
        return [self.get_child_perms(subfolder, request, perm_list)
                for subfolder in children]
    return [folder.has_read_permission(request)]

You don't need an else either as you can only return once from the function.

5 Comments

This seems to work, but not returning values for nested folders, only returns values of folder that contain only files
Add a link to your code, I think there is a simpler way to do what you want
dpaste.com/2ZYA3QB here the code for the plugin, but not sure what you want to see, since this is a plugin for django cms, which is based on django-filer.
Do you actually want boolean values returned based on permissions and only interested in folders?
I think you need to return [folder.has_read_permission(request)]+ [self.get_child_perms(subfolder..., you will need to flatten the the returned list if you want a flatten list, itertools.chain will do it

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.