Fix typing

For some reason, my MyPy started acting up once I started using the PythonPath while calling it.
This commit is contained in:
Jaime van Kessel 2018-09-27 20:01:55 +02:00
parent 57334dd751
commit 3b70e5eb6b
9 changed files with 120 additions and 91 deletions

View File

@ -61,6 +61,7 @@ from cura.Scene.CuraSceneController import CuraSceneController
from UM.Settings.SettingDefinition import SettingDefinition, DefinitionPropertyType
from UM.Settings.ContainerRegistry import ContainerRegistry
from UM.Settings.SettingFunction import SettingFunction
from cura.Settings.CuraContainerRegistry import CuraContainerRegistry
from cura.Settings.MachineNameValidator import MachineNameValidator
from cura.Machines.Models.BuildPlateModel import BuildPlateModel
@ -242,6 +243,8 @@ class CuraApplication(QtApplication):
from cura.Settings.CuraContainerRegistry import CuraContainerRegistry
self._container_registry_class = CuraContainerRegistry
# Redefined here in order to please the typing.
self._container_registry = None # type: CuraContainerRegistry
from cura.CuraPackageManager import CuraPackageManager
self._package_manager_class = CuraPackageManager
@ -266,6 +269,9 @@ class CuraApplication(QtApplication):
help = "FOR TESTING ONLY. Trigger an early crash to show the crash dialog.")
self._cli_parser.add_argument("file", nargs = "*", help = "Files to load after starting the application.")
def getContainerRegistry(self) -> "CuraContainerRegistry":
return self._container_registry
def parseCliOptions(self):
super().parseCliOptions()

View File

@ -1,7 +1,7 @@
# Copyright (c) 2018 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
from typing import Optional
from typing import Optional, List, Dict, Union
import os
import urllib.parse
from configparser import ConfigParser
@ -60,7 +60,7 @@ class SettingVisibilityPresetsModel(ListModel):
def _populate(self) -> None:
from cura.CuraApplication import CuraApplication
items = []
items = [] # type: List[Dict[str, Union[str, int, List[str]]]]
for file_path in Resources.getAllResourcesOfType(CuraApplication.ResourceTypes.SettingVisibilityPreset):
try:
mime_type = MimeTypeDatabase.getMimeTypeForFile(file_path)
@ -79,7 +79,7 @@ class SettingVisibilityPresetsModel(ListModel):
if not parser.has_option("general", "name") or not parser.has_option("general", "weight"):
continue
settings = []
settings = [] # type: List[str]
for section in parser.sections():
if section == 'general':
continue
@ -98,7 +98,7 @@ class SettingVisibilityPresetsModel(ListModel):
except Exception:
Logger.logException("e", "Failed to load setting preset %s", file_path)
items.sort(key = lambda k: (int(k["weight"]), k["id"]))
items.sort(key = lambda k: (int(k["weight"]), k["id"])) # type: ignore
# Put "custom" at the top
items.insert(0, {"id": "custom",
"name": "Custom selection",

View File

@ -6,6 +6,7 @@ from typing import TYPE_CHECKING, Optional, cast, Dict, List
from PyQt5.QtCore import QObject, QTimer, pyqtSignal, pyqtSlot
from UM.Application import Application
from UM.ConfigurationErrorMessage import ConfigurationErrorMessage
from UM.Logger import Logger
from UM.Util import parseBool
@ -40,7 +41,8 @@ class QualityManager(QObject):
def __init__(self, container_registry: "ContainerRegistry", parent = None) -> None:
super().__init__(parent)
self._application = Application.getInstance() # type: CuraApplication
from cura.CuraApplication import CuraApplication
self._application = CuraApplication.getInstance() # type: CuraApplication
self._material_manager = self._application.getMaterialManager()
self._container_registry = container_registry
@ -458,7 +460,7 @@ class QualityManager(QObject):
# stack and clear the user settings.
@pyqtSlot(str)
def createQualityChanges(self, base_name: str) -> None:
machine_manager = Application.getInstance().getMachineManager()
machine_manager = CuraApplication.getInstance().getMachineManager()
global_stack = machine_manager.activeMachine
if not global_stack:

View File

@ -36,7 +36,7 @@ class AuthorizationHelpers:
"code": authorization_code,
"code_verifier": verification_code,
"scope": self._settings.CLIENT_SCOPES
}))
})) # type: ignore
# Request the access token from the authorization server using a refresh token.
# \param refresh_token:
@ -48,7 +48,7 @@ class AuthorizationHelpers:
"grant_type": "refresh_token",
"refresh_token": refresh_token,
"scope": self._settings.CLIENT_SCOPES
}))
})) # type: ignore
@staticmethod
# Parse the token response from the authorization server into an AuthenticationResponse object.

View File

@ -14,7 +14,7 @@ class OAuth2Settings(BaseModel):
CLIENT_ID = None # type: Optional[str]
CLIENT_SCOPES = None # type: Optional[str]
CALLBACK_URL = None # type: Optional[str]
AUTH_DATA_PREFERENCE_KEY = None # type: Optional[str]
AUTH_DATA_PREFERENCE_KEY = "" # type: str
AUTH_SUCCESS_REDIRECT = "https://ultimaker.com" # type: str
AUTH_FAILED_REDIRECT = "https://ultimaker.com" # type: str

View File

@ -5,9 +5,11 @@ from PyQt5.QtCore import QTimer
from UM.Application import Application
from UM.Math.Polygon import Polygon
from UM.Scene.SceneNodeDecorator import SceneNodeDecorator
from UM.Settings.ContainerRegistry import ContainerRegistry
from cura.Settings.ExtruderManager import ExtruderManager
from cura.Scene import ConvexHullNode
@ -18,6 +20,8 @@ from typing import TYPE_CHECKING, Any, Optional
if TYPE_CHECKING:
from UM.Scene.SceneNode import SceneNode
from cura.Settings.GlobalStack import GlobalStack
from UM.Mesh.MeshData import MeshData
from UM.Math.Matrix import Matrix
## The convex hull decorator is a scene node decorator that adds the convex hull functionality to a scene node.
@ -33,17 +37,17 @@ class ConvexHullDecorator(SceneNodeDecorator):
# Make sure the timer is created on the main thread
self._recompute_convex_hull_timer = None # type: Optional[QTimer]
if Application.getInstance() is not None:
Application.getInstance().callLater(self.createRecomputeConvexHullTimer)
from cura.CuraApplication import CuraApplication
if CuraApplication.getInstance() is not None:
CuraApplication.getInstance().callLater(self.createRecomputeConvexHullTimer)
self._raft_thickness = 0.0
self._build_volume = Application.getInstance().getBuildVolume()
self._build_volume = CuraApplication.getInstance().getBuildVolume()
self._build_volume.raftThicknessChanged.connect(self._onChanged)
Application.getInstance().globalContainerStackChanged.connect(self._onGlobalStackChanged)
Application.getInstance().getController().toolOperationStarted.connect(self._onChanged)
Application.getInstance().getController().toolOperationStopped.connect(self._onChanged)
CuraApplication.getInstance().globalContainerStackChanged.connect(self._onGlobalStackChanged)
CuraApplication.getInstance().getController().toolOperationStarted.connect(self._onChanged)
CuraApplication.getInstance().getController().toolOperationStopped.connect(self._onChanged)
self._onGlobalStackChanged()
@ -61,9 +65,9 @@ class ConvexHullDecorator(SceneNodeDecorator):
previous_node.parentChanged.disconnect(self._onChanged)
super().setNode(node)
self._node.transformationChanged.connect(self._onChanged)
self._node.parentChanged.connect(self._onChanged)
# Mypy doesn't understand that self._node is no longer optional, so just use the node.
node.transformationChanged.connect(self._onChanged)
node.parentChanged.connect(self._onChanged)
self._onChanged()
@ -78,9 +82,9 @@ class ConvexHullDecorator(SceneNodeDecorator):
hull = self._compute2DConvexHull()
if self._global_stack and self._node and hull is not None:
if self._global_stack and self._node is not None and hull is not None:
# Parent can be None if node is just loaded.
if self._global_stack.getProperty("print_sequence", "value") == "one_at_a_time" and (self._node.getParent() is None or not self._node.getParent().callDecoration("isGroup")):
if self._global_stack.getProperty("print_sequence", "value") == "one_at_a_time" and not self.hasGroupAsParent(self._node):
hull = hull.getMinkowskiHull(Polygon(numpy.array(self._global_stack.getProperty("machine_head_polygon", "value"), numpy.float32)))
hull = self._add2DAdhesionMargin(hull)
return hull
@ -92,6 +96,13 @@ class ConvexHullDecorator(SceneNodeDecorator):
return self._compute2DConvexHeadFull()
@staticmethod
def hasGroupAsParent(node: "SceneNode") -> bool:
parent = node.getParent()
if parent is None:
return False
return bool(parent.callDecoration("isGroup"))
## Get convex hull of the object + head size
# In case of printing all at once this is the same as the convex hull.
# For one at the time this is area with intersection of mirrored head
@ -100,8 +111,10 @@ class ConvexHullDecorator(SceneNodeDecorator):
return None
if self._global_stack:
if self._global_stack.getProperty("print_sequence", "value") == "one_at_a_time" and (self._node.getParent() is None or not self._node.getParent().callDecoration("isGroup")):
if self._global_stack.getProperty("print_sequence", "value") == "one_at_a_time" and not self.hasGroupAsParent(self._node):
head_with_fans = self._compute2DConvexHeadMin()
if head_with_fans is None:
return None
head_with_fans_with_adhesion_margin = self._add2DAdhesionMargin(head_with_fans)
return head_with_fans_with_adhesion_margin
return None
@ -114,7 +127,7 @@ class ConvexHullDecorator(SceneNodeDecorator):
return None
if self._global_stack:
if self._global_stack.getProperty("print_sequence", "value") == "one_at_a_time" and (self._node.getParent() is None or not self._node.getParent().callDecoration("isGroup")):
if self._global_stack.getProperty("print_sequence", "value") == "one_at_a_time" and not self.hasGroupAsParent(self._node):
# Printing one at a time and it's not an object in a group
return self._compute2DConvexHull()
return None
@ -153,15 +166,17 @@ class ConvexHullDecorator(SceneNodeDecorator):
def _init2DConvexHullCache(self) -> None:
# Cache for the group code path in _compute2DConvexHull()
self._2d_convex_hull_group_child_polygon = None
self._2d_convex_hull_group_result = None
self._2d_convex_hull_group_child_polygon = None # type: Optional[Polygon]
self._2d_convex_hull_group_result = None # type: Optional[Polygon]
# Cache for the mesh code path in _compute2DConvexHull()
self._2d_convex_hull_mesh = None
self._2d_convex_hull_mesh_world_transform = None
self._2d_convex_hull_mesh_result = None
self._2d_convex_hull_mesh = None # type: Optional[MeshData]
self._2d_convex_hull_mesh_world_transform = None # type: Optional[Matrix]
self._2d_convex_hull_mesh_result = None # type: Optional[Polygon]
def _compute2DConvexHull(self) -> Optional[Polygon]:
if self._node is None:
return None
if self._node.callDecoration("isGroup"):
points = numpy.zeros((0, 2), dtype=numpy.int32)
for child in self._node.getChildren():
@ -187,47 +202,47 @@ class ConvexHullDecorator(SceneNodeDecorator):
return offset_hull
else:
offset_hull = None
if self._node.getMeshData():
mesh = self._node.getMeshData()
world_transform = self._node.getWorldTransformation()
# Check the cache
if mesh is self._2d_convex_hull_mesh and world_transform == self._2d_convex_hull_mesh_world_transform:
return self._2d_convex_hull_mesh_result
vertex_data = mesh.getConvexHullTransformedVertices(world_transform)
# Don't use data below 0.
# TODO; We need a better check for this as this gives poor results for meshes with long edges.
# Do not throw away vertices: the convex hull may be too small and objects can collide.
# vertex_data = vertex_data[vertex_data[:,1] >= -0.01]
if len(vertex_data) >= 4:
# Round the vertex data to 1/10th of a mm, then remove all duplicate vertices
# This is done to greatly speed up further convex hull calculations as the convex hull
# becomes much less complex when dealing with highly detailed models.
vertex_data = numpy.round(vertex_data, 1)
vertex_data = vertex_data[:, [0, 2]] # Drop the Y components to project to 2D.
# Grab the set of unique points.
#
# This basically finds the unique rows in the array by treating them as opaque groups of bytes
# which are as long as the 2 float64s in each row, and giving this view to numpy.unique() to munch.
# See http://stackoverflow.com/questions/16970982/find-unique-rows-in-numpy-array
vertex_byte_view = numpy.ascontiguousarray(vertex_data).view(
numpy.dtype((numpy.void, vertex_data.dtype.itemsize * vertex_data.shape[1])))
_, idx = numpy.unique(vertex_byte_view, return_index=True)
vertex_data = vertex_data[idx] # Select the unique rows by index.
hull = Polygon(vertex_data)
if len(vertex_data) >= 3:
convex_hull = hull.getConvexHull()
offset_hull = self._offsetHull(convex_hull)
else:
offset_hull = Polygon([])
mesh = self._node.getMeshData()
if mesh is None:
return Polygon([]) # Node has no mesh data, so just return an empty Polygon.
world_transform = self._node.getWorldTransformation()
# Check the cache
if mesh is self._2d_convex_hull_mesh and world_transform == self._2d_convex_hull_mesh_world_transform:
return self._2d_convex_hull_mesh_result
vertex_data = mesh.getConvexHullTransformedVertices(world_transform)
# Don't use data below 0.
# TODO; We need a better check for this as this gives poor results for meshes with long edges.
# Do not throw away vertices: the convex hull may be too small and objects can collide.
# vertex_data = vertex_data[vertex_data[:,1] >= -0.01]
if len(vertex_data) >= 4: # type: ignore # mypy and numpy don't play along well just yet.
# Round the vertex data to 1/10th of a mm, then remove all duplicate vertices
# This is done to greatly speed up further convex hull calculations as the convex hull
# becomes much less complex when dealing with highly detailed models.
vertex_data = numpy.round(vertex_data, 1)
vertex_data = vertex_data[:, [0, 2]] # Drop the Y components to project to 2D.
# Grab the set of unique points.
#
# This basically finds the unique rows in the array by treating them as opaque groups of bytes
# which are as long as the 2 float64s in each row, and giving this view to numpy.unique() to munch.
# See http://stackoverflow.com/questions/16970982/find-unique-rows-in-numpy-array
vertex_byte_view = numpy.ascontiguousarray(vertex_data).view(
numpy.dtype((numpy.void, vertex_data.dtype.itemsize * vertex_data.shape[1])))
_, idx = numpy.unique(vertex_byte_view, return_index=True)
vertex_data = vertex_data[idx] # Select the unique rows by index.
hull = Polygon(vertex_data)
if len(vertex_data) >= 3:
convex_hull = hull.getConvexHull()
offset_hull = self._offsetHull(convex_hull)
# Store the result in the cache
self._2d_convex_hull_mesh = mesh
self._2d_convex_hull_mesh_world_transform = world_transform
@ -338,7 +353,7 @@ class ConvexHullDecorator(SceneNodeDecorator):
## Private convenience function to get a setting from the correct extruder (as defined by limit_to_extruder property).
def _getSettingProperty(self, setting_key: str, prop: str = "value") -> Any:
if not self._global_stack:
if self._global_stack is None or self._node is None:
return None
per_mesh_stack = self._node.callDecoration("getStack")
if per_mesh_stack:
@ -358,7 +373,7 @@ class ConvexHullDecorator(SceneNodeDecorator):
return self._global_stack.getProperty(setting_key, prop)
## Returns True if node is a descendant or the same as the root node.
def __isDescendant(self, root: "SceneNode", node: "SceneNode") -> bool:
def __isDescendant(self, root: "SceneNode", node: Optional["SceneNode"]) -> bool:
if node is None:
return False
if root is node:

View File

@ -28,10 +28,10 @@ if TYPE_CHECKING:
from cura.Machines.MaterialNode import MaterialNode
from cura.Machines.QualityChangesGroup import QualityChangesGroup
from UM.PluginRegistry import PluginRegistry
from UM.Settings.ContainerRegistry import ContainerRegistry
from cura.Settings.MachineManager import MachineManager
from cura.Machines.MaterialManager import MaterialManager
from cura.Machines.QualityManager import QualityManager
from cura.Settings.CuraContainerRegistry import CuraContainerRegistry
catalog = i18nCatalog("cura")
@ -52,7 +52,7 @@ class ContainerManager(QObject):
self._application = application # type: CuraApplication
self._plugin_registry = self._application.getPluginRegistry() # type: PluginRegistry
self._container_registry = self._application.getContainerRegistry() # type: ContainerRegistry
self._container_registry = self._application.getContainerRegistry() # type: CuraContainerRegistry
self._machine_manager = self._application.getMachineManager() # type: MachineManager
self._material_manager = self._application.getMaterialManager() # type: MaterialManager
self._quality_manager = self._application.getQualityManager() # type: QualityManager
@ -391,7 +391,8 @@ class ContainerManager(QObject):
continue
mime_type = self._container_registry.getMimeTypeForContainer(container_type)
if mime_type is None:
continue
entry = {
"type": serialize_type,
"mime": mime_type,

View File

@ -1148,7 +1148,7 @@ class MachineManager(QObject):
self._fixQualityChangesGroupToNotSupported(quality_changes_group)
quality_changes_container = self._empty_quality_changes_container
quality_container = self._empty_quality_container
quality_container = self._empty_quality_container # type: Optional[InstanceContainer]
if quality_changes_group.node_for_global and quality_changes_group.node_for_global.getContainer():
quality_changes_container = cast(InstanceContainer, quality_changes_group.node_for_global.getContainer())
if quality_group is not None and quality_group.node_for_global and quality_group.node_for_global.getContainer():

View File

@ -21,6 +21,7 @@ from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
from UM.Scene.Selection import Selection
from UM.Signal import Signal
from UM.View.CompositePass import CompositePass
from UM.View.GL.OpenGL import OpenGL
from UM.View.GL.OpenGLContext import OpenGLContext
@ -36,7 +37,7 @@ from .SimulationViewProxy import SimulationViewProxy
import numpy
import os.path
from typing import Optional, TYPE_CHECKING, List
from typing import Optional, TYPE_CHECKING, List, cast
if TYPE_CHECKING:
from UM.Scene.SceneNode import SceneNode
@ -64,7 +65,7 @@ class SimulationView(View):
self._minimum_layer_num = 0
self._current_layer_mesh = None
self._current_layer_jumps = None
self._top_layers_job = None
self._top_layers_job = None # type: Optional["_CreateTopLayersJob"]
self._activity = False
self._old_max_layers = 0
@ -78,10 +79,10 @@ class SimulationView(View):
self._ghost_shader = None # type: Optional["ShaderProgram"]
self._layer_pass = None # type: Optional[SimulationPass]
self._composite_pass = None # type: Optional[RenderPass]
self._old_layer_bindings = None
self._composite_pass = None # type: Optional[CompositePass]
self._old_layer_bindings = None # type: Optional[List[str]]
self._simulationview_composite_shader = None # type: Optional["ShaderProgram"]
self._old_composite_shader = None
self._old_composite_shader = None # type: Optional["ShaderProgram"]
self._global_container_stack = None # type: Optional[ContainerStack]
self._proxy = SimulationViewProxy()
@ -204,9 +205,11 @@ class SimulationView(View):
if not self._ghost_shader:
self._ghost_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "color.shader"))
self._ghost_shader.setUniformValue("u_color", Color(*Application.getInstance().getTheme().getColor("layerview_ghost").getRgb()))
theme = CuraApplication.getInstance().getTheme()
if theme is not None:
self._ghost_shader.setUniformValue("u_color", Color(*theme.getColor("layerview_ghost").getRgb()))
for node in DepthFirstIterator(scene.getRoot()):
for node in DepthFirstIterator(scene.getRoot()): # type: ignore
# We do not want to render ConvexHullNode as it conflicts with the bottom layers.
# However, it is somewhat relevant when the node is selected, so do render it then.
if type(node) is ConvexHullNode and not Selection.isSelected(node.getWatchedNode()):
@ -347,7 +350,7 @@ class SimulationView(View):
self._old_max_layers = self._max_layers
## Recalculate num max layers
new_max_layers = 0
for node in DepthFirstIterator(scene.getRoot()):
for node in DepthFirstIterator(scene.getRoot()): # type: ignore
layer_data = node.callDecoration("getLayerData")
if not layer_data:
continue
@ -398,7 +401,7 @@ class SimulationView(View):
def calculateMaxPathsOnLayer(self, layer_num: int) -> None:
# Update the currentPath
scene = self.getController().getScene()
for node in DepthFirstIterator(scene.getRoot()):
for node in DepthFirstIterator(scene.getRoot()): # type: ignore
layer_data = node.callDecoration("getLayerData")
if not layer_data:
continue
@ -474,15 +477,17 @@ class SimulationView(View):
self._onGlobalStackChanged()
if not self._simulationview_composite_shader:
self._simulationview_composite_shader = OpenGL.getInstance().createShaderProgram(os.path.join(PluginRegistry.getInstance().getPluginPath("SimulationView"), "simulationview_composite.shader"))
theme = Application.getInstance().getTheme()
self._simulationview_composite_shader.setUniformValue("u_background_color", Color(*theme.getColor("viewport_background").getRgb()))
self._simulationview_composite_shader.setUniformValue("u_outline_color", Color(*theme.getColor("model_selection_outline").getRgb()))
plugin_path = cast(str, PluginRegistry.getInstance().getPluginPath("SimulationView"))
self._simulationview_composite_shader = OpenGL.getInstance().createShaderProgram(os.path.join(plugin_path, "simulationview_composite.shader"))
theme = CuraApplication.getInstance().getTheme()
if theme is not None:
self._simulationview_composite_shader.setUniformValue("u_background_color", Color(*theme.getColor("viewport_background").getRgb()))
self._simulationview_composite_shader.setUniformValue("u_outline_color", Color(*theme.getColor("model_selection_outline").getRgb()))
if not self._composite_pass:
self._composite_pass = self.getRenderer().getRenderPass("composite")
self._composite_pass = cast(CompositePass, self.getRenderer().getRenderPass("composite"))
self._old_layer_bindings = self._composite_pass.getLayerBindings()[:] # make a copy so we can restore to it later
self._old_layer_bindings = self._composite_pass.getLayerBindings()[:] # make a copy so we can restore to it later
self._composite_pass.getLayerBindings().append("simulationview")
self._old_composite_shader = self._composite_pass.getCompositeShader()
self._composite_pass.setCompositeShader(self._simulationview_composite_shader)
@ -496,8 +501,8 @@ class SimulationView(View):
self._nozzle_node.setParent(None)
self.getRenderer().removeRenderPass(self._layer_pass)
if self._composite_pass:
self._composite_pass.setLayerBindings(self._old_layer_bindings)
self._composite_pass.setCompositeShader(self._old_composite_shader)
self._composite_pass.setLayerBindings(cast(List[str], self._old_layer_bindings))
self._composite_pass.setCompositeShader(cast(ShaderProgram, self._old_composite_shader))
return False
@ -606,7 +611,7 @@ class _CreateTopLayersJob(Job):
def run(self) -> None:
layer_data = None
for node in DepthFirstIterator(self._scene.getRoot()):
for node in DepthFirstIterator(self._scene.getRoot()): # type: ignore
layer_data = node.callDecoration("getLayerData")
if layer_data:
break