unrealon 2.0.10__py3-none-any.whl → 2.0.12__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,205 @@
1
+ """
2
+ Cross-platform compatibility utilities for UnrealOn Driver.
3
+
4
+ Handles platform-specific configurations and fixes for Windows, macOS, and Linux.
5
+ """
6
+
7
+ import asyncio
8
+ import sys
9
+ import platform
10
+ import warnings
11
+ from typing import Optional
12
+ import logging
13
+
14
+ logger = logging.getLogger(__name__)
15
+
16
+
17
+ class PlatformCompatibility:
18
+ """
19
+ Handles cross-platform compatibility for UnrealOn Driver.
20
+
21
+ Automatically applies platform-specific fixes and configurations
22
+ to ensure consistent behavior across Windows, macOS, and Linux.
23
+ """
24
+
25
+ def __init__(self):
26
+ """Initialize platform compatibility."""
27
+ self.platform = platform.system()
28
+ self.python_version = sys.version_info
29
+ self._applied_fixes = []
30
+
31
+ def apply_all_fixes(self) -> None:
32
+ """
33
+ Apply all platform-specific fixes automatically.
34
+
35
+ This method should be called once at the start of the application
36
+ to ensure optimal cross-platform compatibility.
37
+ """
38
+ logger.info(f"🔧 Applying platform fixes for {self.platform}")
39
+
40
+ if self.platform == "Windows":
41
+ self._apply_windows_fixes()
42
+ elif self.platform == "Darwin": # macOS
43
+ self._apply_macos_fixes()
44
+ elif self.platform == "Linux":
45
+ self._apply_linux_fixes()
46
+
47
+ logger.info(f"✅ Applied {len(self._applied_fixes)} platform fixes: {', '.join(self._applied_fixes)}")
48
+
49
+ def _apply_windows_fixes(self) -> None:
50
+ """Apply Windows-specific fixes."""
51
+
52
+ # Fix 1: Set ProactorEventLoopPolicy for better asyncio performance
53
+ if self.python_version >= (3, 8):
54
+ try:
55
+ asyncio.set_event_loop_policy(asyncio.WindowsProactorEventLoopPolicy())
56
+ self._applied_fixes.append("WindowsProactorEventLoopPolicy")
57
+ logger.debug("✅ Set WindowsProactorEventLoopPolicy for better asyncio performance")
58
+ except Exception as e:
59
+ logger.warning(f"⚠️ Failed to set WindowsProactorEventLoopPolicy: {e}")
60
+
61
+ # Fix 2: Suppress ResourceWarning on Windows
62
+ try:
63
+ warnings.filterwarnings("ignore", category=ResourceWarning)
64
+ self._applied_fixes.append("ResourceWarning suppression")
65
+ logger.debug("✅ Suppressed ResourceWarning for cleaner output")
66
+ except Exception as e:
67
+ logger.warning(f"⚠️ Failed to suppress ResourceWarning: {e}")
68
+
69
+ # Fix 3: Set console encoding to UTF-8 if possible
70
+ try:
71
+ if hasattr(sys.stdout, 'reconfigure'):
72
+ sys.stdout.reconfigure(encoding='utf-8')
73
+ sys.stderr.reconfigure(encoding='utf-8')
74
+ self._applied_fixes.append("UTF-8 console encoding")
75
+ logger.debug("✅ Set console encoding to UTF-8")
76
+ except Exception as e:
77
+ logger.debug(f"Console encoding fix not needed or failed: {e}")
78
+
79
+ # Fix 4: Increase default socket timeout for Windows
80
+ try:
81
+ import socket
82
+ socket.setdefaulttimeout(30.0)
83
+ self._applied_fixes.append("Socket timeout increase")
84
+ logger.debug("✅ Increased default socket timeout to 30s")
85
+ except Exception as e:
86
+ logger.warning(f"⚠️ Failed to set socket timeout: {e}")
87
+
88
+ def _apply_macos_fixes(self) -> None:
89
+ """Apply macOS-specific fixes."""
90
+
91
+ # Fix 1: Handle macOS SSL context issues
92
+ try:
93
+ import ssl
94
+ # Create unverified SSL context for development
95
+ ssl._create_default_https_context = ssl._create_unverified_context
96
+ self._applied_fixes.append("SSL context fix")
97
+ logger.debug("✅ Applied macOS SSL context fix")
98
+ except Exception as e:
99
+ logger.debug(f"SSL context fix not needed: {e}")
100
+
101
+ # Fix 2: Set optimal file descriptor limits
102
+ try:
103
+ import resource
104
+ soft, hard = resource.getrlimit(resource.RLIMIT_NOFILE)
105
+ if soft < 1024:
106
+ resource.setrlimit(resource.RLIMIT_NOFILE, (min(1024, hard), hard))
107
+ self._applied_fixes.append("File descriptor limit increase")
108
+ logger.debug("✅ Increased file descriptor limit")
109
+ except Exception as e:
110
+ logger.debug(f"File descriptor limit fix not needed: {e}")
111
+
112
+ def _apply_linux_fixes(self) -> None:
113
+ """Apply Linux-specific fixes."""
114
+
115
+ # Fix 1: Set optimal file descriptor limits
116
+ try:
117
+ import resource
118
+ soft, hard = resource.getrlimit(resource.RLIMIT_NOFILE)
119
+ if soft < 2048:
120
+ resource.setrlimit(resource.RLIMIT_NOFILE, (min(2048, hard), hard))
121
+ self._applied_fixes.append("File descriptor limit increase")
122
+ logger.debug("✅ Increased file descriptor limit")
123
+ except Exception as e:
124
+ logger.debug(f"File descriptor limit fix not needed: {e}")
125
+
126
+ # Fix 2: Handle display issues for headless environments
127
+ try:
128
+ import os
129
+ if not os.environ.get('DISPLAY'):
130
+ os.environ['DISPLAY'] = ':99'
131
+ self._applied_fixes.append("Headless display fix")
132
+ logger.debug("✅ Set display for headless environment")
133
+ except Exception as e:
134
+ logger.debug(f"Display fix not needed: {e}")
135
+
136
+ def get_platform_info(self) -> dict:
137
+ """
138
+ Get detailed platform information.
139
+
140
+ Returns:
141
+ Dictionary with platform details
142
+ """
143
+ return {
144
+ 'platform': self.platform,
145
+ 'platform_release': platform.release(),
146
+ 'platform_version': platform.version(),
147
+ 'architecture': platform.architecture(),
148
+ 'machine': platform.machine(),
149
+ 'processor': platform.processor(),
150
+ 'python_version': f"{self.python_version.major}.{self.python_version.minor}.{self.python_version.micro}",
151
+ 'python_implementation': platform.python_implementation(),
152
+ 'applied_fixes': self._applied_fixes
153
+ }
154
+
155
+ @classmethod
156
+ def auto_configure(cls) -> 'PlatformCompatibility':
157
+ """
158
+ Automatically configure platform compatibility.
159
+
160
+ This is the recommended way to use this class - it will
161
+ automatically detect the platform and apply all necessary fixes.
162
+
163
+ Returns:
164
+ Configured PlatformCompatibility instance
165
+ """
166
+ compatibility = cls()
167
+ compatibility.apply_all_fixes()
168
+ return compatibility
169
+
170
+
171
+ # Global instance for easy access
172
+ _platform_compatibility: Optional[PlatformCompatibility] = None
173
+
174
+
175
+ def ensure_platform_compatibility() -> PlatformCompatibility:
176
+ """
177
+ Ensure platform compatibility is configured.
178
+
179
+ This function can be called multiple times safely - it will only
180
+ configure compatibility once per application run.
181
+
182
+ Returns:
183
+ PlatformCompatibility instance
184
+ """
185
+ global _platform_compatibility
186
+
187
+ if _platform_compatibility is None:
188
+ _platform_compatibility = PlatformCompatibility.auto_configure()
189
+
190
+ return _platform_compatibility
191
+
192
+
193
+ def get_platform_info() -> dict:
194
+ """
195
+ Get platform information.
196
+
197
+ Returns:
198
+ Dictionary with platform details
199
+ """
200
+ compatibility = ensure_platform_compatibility()
201
+ return compatibility.get_platform_info()
202
+
203
+
204
+ # Auto-configure on import for convenience
205
+ ensure_platform_compatibility()
Binary file
Binary file