Repository: nvaccess/nvda

Issue:
Python 3: division operator differences between classic and the new division
### Steps to reproduce:
Run Python 2 and 3 interpreters and try performing division operation such as "3 / 2" and "3 // 2".

### Actual behavior:
Errors such as not being converted to integer in Python 3.

### Expected behavior:
No errors.

### System configuration
#### NVDA installed/portable/running from source:
Source and installed

#### NVDA version:
master.17384

#### Windows version:
Windows 10 Version 1903

#### Name and version of other software in use when reproducing the issue:
N/A

#### Other information about your system:
N/A

### Other questions
#### Does the issue still occur after restarting your PC?
Yes

#### Have you tried any other versions of NVDA? If so, please report their behaviors.
Yes - source code version of Python 3 NVDA

### Context:
Division operator semantics has changed between Python 2 and 3:

* /: floor division for integers in Python 2, regular division in Python 3
* //: integer division for both Python 2 and 3.

There are places in NVDA that will expect integers via single slash operator when in fact it will return float in Python 3. These include Windows Console handler, GUI, mouse handler and others. Thus either standardize around calling int, or use two slashes. Note that this must be tested extensively to make sure regressions are not introduced.

Thanks.


Discussion:

Resolving patch:
diff --git a/source/gui/__init__.py b/source/gui/__init__.py
--- a/source/gui/__init__.py
+++ b/source/gui/__init__.py
@@ -154,8 +154,10 @@ def showGui(self):
 		# The menu pops up at the location of the mouse, which means it pops up at an unpredictable location.
 		# Therefore, move the mouse to the centre of the screen so that the menu will always pop up there.
 		left, top, width, height = api.getDesktopObject().location
-		x = width / 2
-		y = height / 2
+		# #9641 (Py3 review required): pixel coordinates are integers, not floats.
+		# Thus perform a floor division.
+		x = width // 2
+		y = height // 2
 		winUser.setCursorPos(x, y)
 		self.evaluateUpdatePendingUpdateMenuItemCommand()
 		self.sysTrayIcon.onActivate(None)
diff --git a/source/nvwave.py b/source/nvwave.py
--- a/source/nvwave.py
+++ b/source/nvwave.py
@@ -170,7 +170,9 @@ def open(self):
 			wfx.nChannels = self.channels
 			wfx.nSamplesPerSec = self.samplesPerSec
 			wfx.wBitsPerSample = self.bitsPerSample
-			wfx.nBlockAlign = self.bitsPerSample / 8 * self.channels
+			# #9641 (Py3 review required): wfx.nBlockAlign = ctypes.wintypes.WORD == ctypes.ushort == int.
+			# Thus use floor division so we can obtain an integer.
+			wfx.nBlockAlign = self.bitsPerSample // 8 * self.channels
 			wfx.nAvgBytesPerSec = self.samplesPerSec * wfx.nBlockAlign
 			waveout = HWAVEOUT(0)
 			with self._global_waveout_lock:
diff --git a/source/synthDrivers/oneCore.py b/source/synthDrivers/oneCore.py
--- a/source/synthDrivers/oneCore.py
+++ b/source/synthDrivers/oneCore.py
@@ -349,7 +349,9 @@ def _callback(self, bytes, len, markers):
 			# pos is a time offset in 100-nanosecond units.
 			# Convert this to a byte offset.
 			# Order the equation so we don't have to do floating point.
-			pos = pos * self._bytesPerSec / HUNDRED_NS_PER_SEC
+			# #9641 (Py3 review required): one way to ensure no floating point is doing a floor division to obtain an integer.
+			# Because one slash operator will do true division in Python 3, which will return a float.
+			pos = pos * self._bytesPerSec // HUNDRED_NS_PER_SEC
 			# Push audio up to this marker.
 			self._player.feed(data[prevPos:pos],
 				onDone=lambda index=index: synthIndexReached.notify(synth=self, index=index))


Test patch: