Skip to content

Commit 6d25384

Browse files
committed
chore: bump version to 1.0.1 and modernize to Python 3.10+
BREAKING CHANGE: Now requires Python 3.10 or higher - Updated Python requirement from 3.8+ to 3.10+ - Modernized type hints using built-in types (str | None, dict[], list[]) - Removed legacy typing imports (Optional, Dict, List) - Updated GitHub Actions to test only Python 3.10, 3.11, 3.12, 3.13 - Updated all documentation to reflect new Python requirement This change ensures Windows CI tests pass and positions the project for the future with cleaner, more maintainable code.
1 parent ccc061f commit 6d25384

File tree

8 files changed

+23
-27
lines changed

8 files changed

+23
-27
lines changed

.github/workflows/tests.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@ jobs:
1313
fail-fast: false
1414
matrix:
1515
os: [ubuntu-latest, windows-latest, macos-latest]
16-
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12']
17-
# Note: Python 3.13 not yet fully supported by GitHub Actions
16+
python-version: ['3.10', '3.11', '3.12', '3.13']
1817

1918
steps:
2019
- uses: actions/checkout@v3

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ If applicable, add screenshots to help explain your problem.
6262

6363
**Environment:**
6464
- OS: [e.g. Windows 10, Ubuntu 22.04]
65-
- Python Version: [e.g. 3.9.7]
65+
- Python Version: [e.g. 3.10.0 or higher]
6666
- nmap Version: [e.g. 7.92]
6767
- Simple LAN Scanner Version: [e.g. 1.0.0]
6868

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
# Simple LAN Scanner
22

3+
[![CI](https://github.com/IBN5100-0/simple-lan-scanner/actions/workflows/tests.yml/badge.svg)](https://github.com/IBN5100-0/simple-lan-scanner/actions/workflows/tests.yml)
34
[![PyPI](https://img.shields.io/pypi/v/simple-lan-scanner.svg)](https://pypi.org/project/simple-lan-scanner/)
4-
[![Python](https://img.shields.io/badge/python-3.8%2B-blue)](https://www.python.org/downloads/)
5+
[![Python](https://img.shields.io/badge/python-3.10%2B-blue)](https://www.python.org/downloads/)
56
[![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
67
[![Requires nmap](https://img.shields.io/badge/requires-nmap-orange.svg)](https://nmap.org/)
78
[![Documentation](https://img.shields.io/badge/docs-latest-brightgreen)](docs/DOCUMENTATION.md)
@@ -41,7 +42,7 @@ pip install -e .[cli]
4142

4243
### Requirements
4344

44-
- Python 3.8+
45+
- Python 3.10+
4546
- [nmap](https://nmap.org/download.html) installed and in PATH
4647

4748
### Basic Usage

docs/DOCUMENTATION.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
[![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
44
[![Version](https://img.shields.io/badge/version-1.0.0-green.svg)](https://github.com/IBN5100-0/simple-lan-scanner/releases/tag/v1.0.0)
5-
[![Python 3.7+](https://img.shields.io/badge/python-3.7+-blue.svg)](https://www.python.org/downloads/)
5+
[![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
66
[![nmap required](https://img.shields.io/badge/requires-nmap-orange.svg)](https://nmap.org/)
77

88
## Table of Contents
@@ -53,7 +53,7 @@ The tool leverages the power of nmap for accurate network scanning while providi
5353

5454
### Prerequisites
5555

56-
1. **Python 3.7 or higher**
56+
1. **Python 3.10 or higher**
5757
```bash
5858
python --version # Verify Python installation
5959
```

pyproject.toml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,19 @@
11
[project]
22
name = "simple_lan_scanner"
3-
version = "1.0.0"
3+
version = "1.0.1"
44
description = "A Python LAN scanning tool that uses nmap to discover devices on the local network"
55
authors = [
66
{name = "Adam Zalewski", email = "me@yamero.online"}
77
]
88
license = {text = "MIT"}
99
readme = "README.md"
10-
requires-python = ">=3.8"
10+
requires-python = ">=3.10"
1111
keywords = ["network", "scanner", "nmap", "lan", "monitoring"]
1212
classifiers = [
1313
"Development Status :: 5 - Production/Stable",
1414
"Intended Audience :: System Administrators",
1515
"License :: OSI Approved :: MIT License",
1616
"Programming Language :: Python :: 3",
17-
"Programming Language :: Python :: 3.8",
18-
"Programming Language :: Python :: 3.9",
1917
"Programming Language :: Python :: 3.10",
2018
"Programming Language :: Python :: 3.11",
2119
"Programming Language :: Python :: 3.12",

src/simple_scanner/gui.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from tkinter import ttk, filedialog, messagebox
55
import datetime
66
import threading
7-
from typing import Optional, Dict, Any
7+
from typing import Any
88
import os
99
import json
1010
from pathlib import Path
@@ -16,7 +16,7 @@
1616
class ModernSettingsDialog(tk.Toplevel):
1717
"""Modern settings dialog with tabs and better organization."""
1818

19-
def __init__(self, parent: tk.Tk, settings: Dict[str, Any]) -> None:
19+
def __init__(self, parent: tk.Tk, settings: dict[str, Any]) -> None:
2020
super().__init__(parent)
2121
self.title("Settings")
2222
self.geometry("600x500")
@@ -359,7 +359,7 @@ def __init__(self) -> None:
359359
self._running = False
360360
self._devices_cache: list[Device] = []
361361
self._last_device_count = 0
362-
self.monitor: Optional[NetworkMonitor] = None
362+
self.monitor: NetworkMonitor | None = None
363363
self.online_only_var = tk.BooleanVar(value=False)
364364

365365
self._create_menu()
@@ -746,7 +746,7 @@ def _show_about(self) -> None:
746746
"A modern network discovery tool\n\n"
747747
"Built with Python and Tkinter")
748748

749-
def _load_settings(self) -> Dict[str, Any]:
749+
def _load_settings(self) -> dict[str, Any]:
750750
"""Load settings from disk or return defaults."""
751751
settings_file = get_user_data_dir() / "gui_settings.json"
752752

src/simple_scanner/models.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,32 @@
11
import datetime
22
from dataclasses import dataclass, field
3-
from typing import Optional
43

54
@dataclass
65
class Device:
76
"""Represents a network device discovered via nmap ping scan."""
87
mac_address: str
98
ip_address: str
10-
hostname: Optional[str] = None
11-
manufacturer: Optional[str] = None
9+
hostname: str | None = None
10+
manufacturer: str | None = None
1211
date_added: datetime.datetime = field(default_factory=lambda: datetime.datetime.now(datetime.timezone.utc))
1312
last_seen: datetime.datetime = field(default_factory=lambda: datetime.datetime.now(datetime.timezone.utc))
1413

1514
def __post_init__(self):
1615
"""Normalize MAC address to lowercase."""
1716
self.mac_address = self.mac_address.lower()
1817

19-
def update_last_seen(self, timestamp: Optional[datetime.datetime] = None) -> None:
18+
def update_last_seen(self, timestamp: datetime.datetime | None = None) -> None:
2019
self.last_seen = timestamp or datetime.datetime.now(datetime.timezone.utc)
2120

2221
def update_ip_address(self, ip_address: str) -> None:
2322
"""Update the IP address (useful for DHCP changes)."""
2423
self.ip_address = ip_address
2524

26-
def update_hostname(self, hostname: Optional[str]) -> None:
25+
def update_hostname(self, hostname: str | None) -> None:
2726
"""Update the hostname."""
2827
self.hostname = hostname
2928

30-
def update_manufacturer(self, manufacturer: Optional[str]) -> None:
29+
def update_manufacturer(self, manufacturer: str | None) -> None:
3130
"""Update the manufacturer."""
3231
self.manufacturer = manufacturer
3332

src/simple_scanner/scanner.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
import json
88
import os
99
from pathlib import Path
10-
from typing import Dict, List, Optional
1110
from .models import Device
1211

1312

@@ -82,7 +81,7 @@ class NetworkMonitor:
8281

8382
def __init__(
8483
self,
85-
network: Optional[str] = None,
84+
network: str | None = None,
8685
remove_stale: bool = False,
8786
verbose: bool = False,
8887
use_persistence: bool = True,
@@ -91,7 +90,7 @@ def __init__(
9190
self.remove_stale = remove_stale
9291
self.verbose = verbose
9392
self.use_persistence = use_persistence
94-
self._devices: Dict[str, Device] = {}
93+
self._devices: dict[str, Device] = {}
9594

9695
# Locate nmap executable
9796
self._nmap_path = shutil.which('nmap')
@@ -190,8 +189,8 @@ def _parse(self, raw: str) -> None:
190189
continue
191190
ip = host_match.group('ip')
192191
hostname = host_match.group('hostname') # May be None
193-
mac: Optional[str] = None
194-
manufacturer: Optional[str] = None
192+
mac: str | None = None
193+
manufacturer: str | None = None
195194

196195
# Look ahead for MAC Address line
197196
for j in range(i+1, min(i+1+self.MAC_LOOKAHEAD_LINES, len(lines))):
@@ -243,7 +242,7 @@ def scan(self) -> None:
243242
print(raw)
244243
self._parse(raw)
245244

246-
def devices(self) -> List[Device]:
245+
def devices(self) -> list[Device]:
247246
"""Return list of tracked devices."""
248247
return list(self._devices.values())
249248

0 commit comments

Comments
 (0)