Comments (5)
oh wow sorry i was just doing more dynamic typing stuff and came back and realized i really misread what was going on. i thought the problem was for general dynamically created methods, not for the case in OP where the methods are known beforehand.
Not sure if y'all were looking to like actually change the dynamically assigned attrs and handle that in a different way, but here's another option that involves no changes to the runtime code. It's a little uh verbose (dynamically assigning in a loop doesn't work for the same reason pyright can't infer from the setattr
/getattr
combo) but it is simple and works:
from typing import TYPE_CHECKING
# ...
class GraphicsLayoutWidget(GraphicsView):
# ...
def __init__(self, ...):
# ...
if TYPE_CHECKING:
nextRow = GraphicsLayout.nextRow
nextCol = GraphicsLayout.nextCol
nextColumn = GraphicsLayout.nextColumn
addPlot = GraphicsLayout.addPlot
addViewBox = GraphicsLayout.addViewBox
addItem = GraphicsLayout.addItem
getItem = GraphicsLayout.getItem
addLayout = GraphicsLayout.addLayout
addLabel = GraphicsLayout.addLabel
removeItem = GraphicsLayout.removeItem
itemIndex = GraphicsLayout.itemIndex
clear = GraphicsLayout.clear
from pyqtgraph.
I've low-key hated those dynamically allocated methods for a variety of reasons, they're tough to document, auto-completion in editors doesn't work and of course type annotations don't work either.
Of the suggestions proposed, I would imagine the @property
method would be "best", seems to address all the issues above, but having another callable as a property certainly seems "weird"
That said, I'm curious how matplotlib handles this, I think they started type-annotating their code, and the same methods are used in a variety of objects.
from pyqtgraph.
I agree that calling a property feels weird, even if it is the most straight forward.
I can't find an instance of Matplotlib copying a function definition, but it's a dense library, so I may have missed it. It does seem like they use a docstring decorator to copy over function docstrings, but nothing about type hints.
I know Plotly uses a lot of copied definitions between functions, but I think they mostly use **kwargs
and leave it up to the docstring to provide the necessary information. I think they generate most of the code used in the library with other scripts based on the state of Plotly.js, so it may not be a fair comparison.
typing.Unpack
could be useful, but it seems like it's probably more trouble than it's worth for small functions.
Here's a thread I opened about a similar issue in Xarray (but hasn't received any new comments): pydata/xarray#8136. One approach they suggest is to add a .pyi
file, however, I think that would be another place to maintain type hints, which sort of defeats the purpose.
I messed around with the signature copier decorator, but I didn't have much luck getting it to work. Maybe using @property
is the best thing to do for now until "proper" signature copying is implemented into the language.
from pyqtgraph.
Copying my reply from discord here (note have not fully read this thread yet):
Yeah... in general dynamic behavior is not conducive to static type checking...
In mpl, we do have some aliasing that is handled by a class decorator, such as set_ha which is the short form of set_horizontalalignment (among many others). We have opted to not type hint those things that are aliased dynamically like that. In our case the official guidance is to use the canonical name in the type checked setting, which is type hinted.
In mpl's case, we technically have the ability to put the type hints in the .pyi files, but I chose not to since it seems silly to expand out the class decorator, and it would make it harder for us to inline type hints should we ever choose to do so (no active plans though on that front)
As for CI, we have a file with specific ignores (for stubtest, which is mypy's program to validate .pyi files against implementation), which actually includes almost everything except the aliases and such, because we generate the most common cases with a script, so that individual PR authors don't have to think about the stubtest exceptions as often:
- https://github.com/matplotlib/matplotlib/blob/main/ci/mypy-stubtest-allowlist.txt
- https://github.com/matplotlib/matplotlib/blob/main/tools/stubtest.py
In this case, I think perhaps rewriting these so that they are more static friendly may be possible...
Not finding the obvious solution immediately, but feels possible, I think one step would be unrolling the loop, which I think will help static checkers...
In mpl we have a similar pass through implented as _axis_method_wrapper for various things that are wrapped in Axes that are actually canonically held in the x/y Axis. However in this case I just typed them in pyi
- https://github.com/matplotlib/matplotlib/blob/main/lib/matplotlib/axes/_base.py#L2176
- https://github.com/matplotlib/matplotlib/blob/main/lib/matplotlib/axes/_base.py#L35
- https://github.com/matplotlib/matplotlib/blob/main/lib/matplotlib/axes/_base.pyi#L253
from pyqtgraph.
Fwiw I have actually found dynamically generating .pyi files is not as bad as it seems:
https://github.com/p2p-ld/numpydantic/blob/main/src/numpydantic/meta.py
from pyqtgraph.
Related Issues (20)
- Automatic smart, human like offset calculation like in matplotlib
- removeItem
- Windows only: bad performence / stuck when QApplication and QMainWindow are used? HOT 4
- RuntimeError: pyqtgraph.opengl: Requires >= OpenGL 2.0 (not ES); Found b'OpenGL ES 3.2 NVIDIA 555.58.02' HOT 9
- ClipToView() range is not correct on the right
- Issue with Moving Parameters in Parameter Trees
- functions: FLOAT_REGEX cannot properly match suffix that starts with "°" (degree) character
- Shift + Dragging QTreeWidgetItem Deletes All Widgets Inside
- CompositionMode is not set if sepcified in ScatterPlotItem constructor and setData
- Display Plot Using pg.PColorMeshItem in Pyqtgraph HOT 1
- DockArea's restoreState is broken when a Dock was undocked and re-docked before calling saveState
- Request: limit upper/bottom units when auto SI-scaling HOT 5
- Parameter of type int does not update correctly when a float is submitted
- Infinite loop in axis redraw HOT 1
- Intermittent exception thrown trying to update ImageItem HOT 1
- Potential Race Conditions Leading to the Unexpected Initialization of a QListWidgetItem Instead of the Widget I Want HOT 10
- pyqtgraph draws an extra line per series when using a custom downsampling class HOT 2
- Why does lookup table not respect autoLevels=False min and max levels? HOT 1
- Dark/Light mode change will no longer work in PySide6 > 6.7.2
- The bottom axis label display incomplete in version 0.13.7 HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from pyqtgraph.