Skip to content

Commit

Permalink
Add example of invalid item_class getting
Browse files Browse the repository at this point in the history
  • Loading branch information
M1troll committed Nov 14, 2024
1 parent 7f8257c commit 98c79ce
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 2 deletions.
2 changes: 1 addition & 1 deletion demo/pages/search_page/components/package_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class PackageList(ListComponent[Package, PyPIPage]):
# By default `ListComponent` have `item_class` attribute with stored first
# Generic variable (Package in current case). But during
# development/inheritance/addition of other generic variables it may become
# unavailable.
# invalid.

# In this case it is necessary to explicitly set `item_class` attribute:
# item_class = Package
Expand Down
65 changes: 64 additions & 1 deletion docs/developer_interface.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,72 @@ Page
Components
*******************************************************************************

.. automodule:: pomcorn.component
.. autoclass:: pomcorn.component.Component
:members:

.. autoclass:: pomcorn.component.ListComponent
:members:

Invalid ``item_class`` case
-------------------------------------------------------------------------------

Here is an example of a case where the automatic filling of ``item_class``
attribute of a generic variable may be incorrect:

.. code-block:: python
from typing import Generic, TypeVar
from pomcorn import Component, ListComponent, Page, locators
from selenium import webdriver as selenium_webdriver
# pypi search page
url = "https://pypi.org/search/?q=saritasa&o="
# Set browser's language to English
options = selenium_webdriver.ChromeOptions()
prefs = {"intl.accept_languages": "en,en_U"}
options.add_experimental_option("prefs", prefs)
# Open page
webdriver = selenium_webdriver.Chrome(options)
page = Page.open(webdriver, app_root=url)
# Prepare out item class component
class ExpectedItemClass(Component[Page]):...
# Implement list component from which another component with generic variable will inherit
TPage = TypeVar("TPage")
class ListItem(Generic[TPage], ListComponent[ExpectedItemClass, TPage]):
base_locator = locators.PropertyLocator(
prop="aria-label",
value="Search results",
)
relative_base_locator = locators.TagNameLocator("li")
# Create a descendant and pass a generic variable to it
class InheritedList(ListItem[Page]):...
# Check current `item_class`
print(f"`InheritedList.item_class` is `{InheritedList(page).item_class}` now")
# `InheritedList.item_class` is `<class 'pomcorn.page.Page'>` now
# Instead of specified `<class '__main__.ExpectedItemClass'>`
webdriver.close()
To solve this problem just specify ``item_class`` right in ``InheritedList``:

.. code-block:: python
...
class InheritedList(ListItem[Page]):...
item_class = ExpectedItemClass
# Check current `item_class`
print(f"`InheritedList.item_class` is `{InheritedList(page).item_class}` now")
# `InheritedList.item_class` is `<class '__main__.ExpectedItemClass'>` now
PomcornElement
*******************************************************************************
Expand Down
13 changes: 13 additions & 0 deletions pomcorn/component.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,19 @@ class ListComponent(Generic[ListItemType, TPage], Component[TPage]):
"""

item_class: type[ListItemType]
"""By default this attr is automatically filled by first generic variable.
But when you develop/inherit/add other generic variables, it may become
invalid. So if you encounter strange behavior of ``item_class``, reconsider
generics/inheritance or just override `item_class` directly in the class.
An example of such a case is given in the documentation:
http://pomcorn.rtfd.io/en/latest/developer_interface.html#invalid-item-class-case
If specified `item_class` and first generic variable match - you will see
a warning that you can delete this overridden attribute.
"""

item_locator: locators.XPathLocator | None = None
relative_item_locator: locators.XPathLocator | None = None
Expand Down

0 comments on commit 98c79ce

Please sign in to comment.