Plone.api.content creating content in improper folder

Situation: Plone 5.2 with the following test setup (which should create a Folder in the portal root with a contained Document):


        folder = plone.api.content.create(
                type='Folder',
                container=self.portal,
                id='folder')

        document = plone.api.content.create(
                type='Document',
                container=self.portal['folder'],
                id='document2')

However the Document is created within the Plone root instead of the created Folder:

50                     type='Folder',
51                     container=self.portal,
52                     id='folder')
53  
54             import pdb; pdb.set_trace()
55  ->         document = plone.api.content.create(
56                     type='Document',
57                     container=self.portal['folder'],
58                     id='document2')
59  
60             IUnavailable(folder).unavailable = True

(Pdb) folder
<Item at /plone/folder>

(Pdb) doc = plone.api.content.create(type='Document', container=folder, id='testdoc')
*** AttributeError: __getitem__

(Pdb) folder.aq_parent
<PloneSite at /plone>

(Pdb) folder.aq_parent.objectIds()
['portal_setup' ....., 'folder', 'testdoc']

Bug or feature?

It works fine in default Plone 5.2 with a default addon.

Taken from memory:

   myfolder = plone.api.content.create(
            type='Folder',
            container=self.portal,
            id='folder')

    document = plone.api.content.create(
            type='Document',
            container=myfolder,
            id='document2')

..irrelevant...both objects are identical.

hmmm. I have similar code in a setuphandler where it works. Can not spot any difference… same with this:

https://github.com/espenmn/medialog.bergensiana/blob/master/medialog/bergensiana/setuphandlers.py#L79-L99

@zopyx Plone 5.2 ...., in python2 or python3 mode? and which minor version?

Plone 5.2, Python 3.7.5.

Clearly the invokeFactory() call is doing something strange..had not time for further debugging.

Are you sure?
Is

container=self.portal['folder'],

correct syntax (what is self here ), should it not be like

portal = api.portal.get()

…

container=portal['folder'],

Sorry but this barely nonsense.

Passing a folder instance as container is supposed to work.

Hi Andreas,

if you are in a (unit-)test setup, a folder with the ID folder might already exist (from some test layer). Can you do a self.portal.objectIds() before you create the folder to check this or use another ID?

Sometimes I also encounter similar issues in tests when creating new content and need to do an explicit transaction.commit() after it.

However, neither did I dig any deeper into that code. Maybe you can also do an invokeFactory instead of plone.api.content.create to see if the issue remains.

Regards, Ramon

No. And if there were another folder then the content would be created inside this folder but not in the Plone root.

Need to investigate this in 2020 after vacation.

This is just lazy. Noone can replicate your problem and we all have code like that working fine.

My guess is that your content-type Folder is itemish and not folderish. For default-Plone with plone.app.contenttypes the __repr__ of the item calles folder you create at the start of your code should be:

<Folder at /plone/folder>

For you it is

<Item at /plone/folder>

No, plone.api would raise then an error similar to this one:

*** BadRequest: The id "folder" is invalid - it is already in use.

Which could lead to unexpected results in a test setup.

But I think the response from @pbauer is more likely.

Anyhow, more investigation here needed with the actual code and database.