pythonx-compose 0.1.0a1__py3-none-any.whl → 0.1.0a2__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.
@@ -1 +1 @@
1
- # GENERATED by scripts/gen_stubs.py from python-multiplatform's Kotlin-named stubs (artifact kotlin-stubs, workflow run 37103737430, commit a5028618, Compose 1.11.1). Do not edit.
1
+ # GENERATED by scripts/gen_stubs.py from python-multiplatform's Kotlin-named stubs (artifact kotlin-stubs, workflow run 37131041879, commit 452cc807, Compose 1.11.1). Do not edit.
@@ -1,33 +1,29 @@
1
1
  """The one rule that makes a `pythonx.compose.*` module a Pythonic view of a Kotlin package.
2
2
 
3
- The binder (`python-multiplatform`) serves every bound Kotlin package under its **Kotlin** name --
4
- `androidx.compose.foundation.layout` -- with Kotlin's own surface: declaration names, keyword
5
- arguments by Kotlin parameter name, Kotlin defaults, overload dispatch. It renames nothing, and it
6
- publishes what a Pythonic layer needs to rename by rule: `inspect.signature(fn)` with the Kotlin
7
- parameter names, and `python_multiplatform.describe(fn)` with one dict per overload.
3
+ The binder (`python-multiplatform`) serves every bound Kotlin package under its **Kotlin** name
4
+ (`androidx.compose.foundation.layout`), and since its #131 it also serves the Pythonic spellings
5
+ itself: snake_case names and keyword arguments, by this module's rule (`python_name`), with the
6
+ Kotlin spelling still working and `inspect.signature` reporting the snake_case keywords. It never
7
+ renames a namespace: `pythonx` is this package.
8
8
 
9
- This module is that layer. A mapped package's `__init__.py` is one line::
9
+ This module groups those Kotlin packages into `pythonx.compose.*`. A mapped package's `__init__.py`
10
+ is one line::
10
11
 
11
12
  __getattr__, __dir__ = reexport(__name__)
12
13
 
13
14
  and every name in it then resolves against the Kotlin package `pythonx-map.toml` maps it to:
14
15
 
15
- - **Names.** A name that starts upper-case -- a type, an object, a `@Composable` -- keeps its Kotlin
16
- spelling (`Modifier`, `Text`). Any other name is reached by its snake_case spelling only
16
+ - **Names.** A name that starts upper-case (a type, an object, a `@Composable`) keeps its Kotlin
17
+ spelling (`Modifier`, `Text`). Any other name is listed and reached by its snake_case spelling
17
18
  (`fillMaxWidth` -> `fill_max_width`, `toURLString` -> `to_url_string`), and an explicit overload
18
- keeps its suffix (`padding__Dp`). The inverse is never computed: the module's real Kotlin names
19
- are converted forward and looked up, so a name the reverse rule could not invert still resolves.
20
- - **Keywords.** `on_click=` reaches the parameter Kotlin calls `onClick`, matched against the
21
- declaration's own parameter names (every overload's), never derived.
22
- - **Signatures.** A re-exported function answers `inspect.signature` with the snake_case names;
23
- defaults stay `python_multiplatform.KOTLIN_DEFAULT`.
19
+ keeps its suffix (`padding__Dp`). The rule is applied forward to the module's real Kotlin names,
20
+ so a name the reverse rule could not invert still resolves.
21
+ - **Functions** are the binder's own callables; their keywords and signatures are the binder's.
24
22
  - **Value classes.** The manifest's `raw-primitive-allowed` list is handed to the binder once per
25
23
  installed binding layer, so `padding(16)` reaches a `Dp` parameter.
26
- - **Methods on a proxy.** The same name rule is registered as the binder's member resolver, so
27
- `Modifier.padding(16).fill_max_width()` reaches `fillMaxWidth` on a proxy Kotlin returned, and
28
- `m.padding(padding_values=...)` reaches `paddingValues`: the resolver also answers a keyword map,
29
- read from `python_multiplatform.describe_member`. The Kotlin spelling still works. The binder
30
- caches the alias in its own registry; its proxy classes keep Kotlin names in `dir()`.
24
+ - **Methods on a proxy** are the binder's: since python-multiplatform #131 it serves
25
+ `Modifier.padding(16).fill_max_width()` and `m.padding(padding_values=...)` itself, by this
26
+ package's rule, with the Kotlin spelling still working. Nothing here takes part.
31
27
 
32
28
  - **Grouped constants.** Inside a Kotlin object served as a namespace, a type nested in it that
33
29
  is not one of its members groups the constants declared as exactly that type, so the notebook's
@@ -50,7 +46,6 @@ from __future__ import annotations
50
46
 
51
47
  import importlib
52
48
  import importlib.util
53
- import inspect
54
49
  import re
55
50
  import sys
56
51
  import types
@@ -116,77 +111,16 @@ def binding_layer():
116
111
  _PRIMED = weakref.WeakSet()
117
112
 
118
113
 
119
- _MEMBER_KEYWORDS: "weakref.WeakKeyDictionary" = weakref.WeakKeyDictionary()
120
-
121
-
122
- def _method_keywords(kotlin_type_name: str, kotlin_member_name: str) -> dict:
123
- """`{snake_case(p): p}` for every parameter `p` of every declaration of a proxy's member.
124
-
125
- Read with `python_multiplatform.describe_member`, which lists each overload's parameters without
126
- invoking anything (the receiver slot is not among them). It is metadata, so it is kept per
127
- (type, member), under the `describe_member` of the binding layer that answered: a new layer
128
- starts with an empty table. A keyword whose snake_case spelling is its own is left out, and a
129
- binder without `describe_member`, or a member it does not describe, has no map.
130
- """
131
- describe_member = getattr(sys.modules.get(ROOT_MODULE), "describe_member", None)
132
- if describe_member is None:
133
- return {}
134
- try:
135
- known = _MEMBER_KEYWORDS.setdefault(describe_member, {})
136
- except TypeError: # something that cannot be weakly referenced: nothing to key a cache by
137
- known = {}
138
- key = (kotlin_type_name, kotlin_member_name)
139
- if key not in known:
140
- keywords: dict = {}
141
- try:
142
- declarations = describe_member(kotlin_type_name, kotlin_member_name)
143
- except (TypeError, AttributeError):
144
- declarations = ()
145
- for declaration in declarations:
146
- for parameter in declaration.get("parameters", ()):
147
- kotlin_parameter = parameter.get("name")
148
- if kotlin_parameter and snake_case(kotlin_parameter) != kotlin_parameter:
149
- keywords.setdefault(snake_case(kotlin_parameter), kotlin_parameter)
150
- known[key] = keywords
151
- return known[key]
152
-
153
-
154
- def member_name(kotlin_type_name: str, requested: str, kotlin_member_names):
155
- """The binder's member-resolver hook: the Kotlin member a Pythonic name means on a proxy, and
156
- the keywords it takes.
157
-
158
- The binder asks for a name its proxy has no Kotlin member of
159
- (`python_multiplatform.binding.add_member_resolver`): the rule is the module rule applied
160
- forward to the proxy's real member names, so `fill_max_width` finds `fillMaxWidth`. It asks
161
- again for a Kotlin member name when a call passes keywords. The answer is then
162
- `(kotlin_name, {python_keyword: kotlinParameter})`, the parameters of every overload of that
163
- member, so `m.padding(padding_values=...)` reaches `paddingValues`. Without a keyword to map the
164
- answer is the name alone, which is all a binder without `describe_member` can be given.
165
- """
166
- if requested in kotlin_member_names:
167
- target = requested
168
- else:
169
- matches = [name for name in kotlin_member_names if python_name(name) == requested]
170
- target = matches[0] if len(matches) == 1 else None
171
- if target is None:
172
- return None
173
- keywords = _method_keywords(kotlin_type_name, target)
174
- return (target, keywords) if keywords else target
175
-
176
-
177
114
  def _prime(binding) -> None:
178
- """Hand this binding layer the manifest's value-class allowlist and the member rule, once.
115
+ """Hand this binding layer the manifest's value-class allowlist, once.
179
116
 
180
- The member rule needs python-multiplatform's `add_member_resolver`; on a binder without it,
181
- methods on a returned proxy stay reachable by their Kotlin names only.
117
+ Method names and keywords on a proxy are the binder's own since python-multiplatform #131
118
+ (snake_case by this package's rule); nothing is registered for them here.
182
119
  """
183
120
  if binding in _PRIMED:
184
121
  return
185
122
  for kotlin_type in manifest().get("value-classes", {}).get("raw-primitive-allowed", ()):
186
123
  binding.allow_raw_primitive(kotlin_type)
187
- add_member_resolver = getattr(binding, "add_member_resolver", None)
188
- if add_member_resolver is not None:
189
- add_member_resolver(member_name)
190
124
  _PRIMED.add(binding)
191
125
 
192
126
 
@@ -233,72 +167,14 @@ def _declared_type(kotlin, kotlin_name: str):
233
167
  return described.get("kind"), described.get("returns")
234
168
 
235
169
 
236
- def _describe(fn):
237
- root = sys.modules.get(ROOT_MODULE)
238
- if root is None or not hasattr(root, "describe"):
239
- return ()
240
- try:
241
- return root.describe(fn)
242
- except (TypeError, AttributeError):
243
- return ()
244
-
245
-
246
- class PythonicFunction:
247
- """A binder callable seen through the naming rule: snake_case keywords and signature.
248
-
249
- Calls go straight to the binder's callable with the keywords translated; overload selection,
250
- defaults and value classes are the binder's. A keyword that matches no parameter is passed on
251
- unchanged, so the binder's own refusal -- which lists the candidates -- is what the caller sees.
252
- """
253
-
254
- __slots__ = ("_kotlin", "_keywords", "__name__", "__qualname__")
255
-
256
- def __init__(self, kotlin_fn, name):
257
- self._kotlin = kotlin_fn
258
- self.__name__ = name
259
- self.__qualname__ = name
260
- keywords = {}
261
- for row in _describe(kotlin_fn):
262
- for parameter in row.get("parameters", ()):
263
- kotlin_parameter = parameter["name"]
264
- keywords.setdefault(snake_case(kotlin_parameter), kotlin_parameter)
265
- self._keywords = keywords
266
-
267
- @property
268
- def __kotlin__(self):
269
- """The binder's callable this wraps."""
270
- return self._kotlin
271
-
272
- @property
273
- def __kotlin_rows__(self):
274
- return self._kotlin.__kotlin_rows__
275
-
276
- @property
277
- def __signature__(self):
278
- kotlin_signature = inspect.signature(self._kotlin)
279
- return kotlin_signature.replace(parameters=[
280
- parameter if parameter.kind in (parameter.VAR_POSITIONAL, parameter.VAR_KEYWORD)
281
- else parameter.replace(name=snake_case(parameter.name))
282
- for parameter in kotlin_signature.parameters.values()
283
- ])
284
-
285
- def __call__(self, *args, **kwargs):
286
- if kwargs:
287
- kwargs = {self._keywords.get(key, key): value for key, value in kwargs.items()}
288
- return self._kotlin(*args, **kwargs)
289
-
290
- def __repr__(self):
291
- return f"<pythonx function {self.__name__} -> {self._kotlin!r}>"
292
-
293
-
294
170
  def _pythonic(value, name):
295
171
  if isinstance(value, types.ModuleType):
296
172
  # A Kotlin object served as a sub-package. Since python-multiplatform #35 the binder lists it
297
173
  # and exposes it as an attribute of its parent, so the name table reaches it directly.
298
- return KotlinObject(value)
299
- if isinstance(value, type) or not callable(value):
300
- return value
301
- return PythonicFunction(value, name)
174
+ return _kotlin_object(value)
175
+ # A function is the binder's own callable: since python-multiplatform #131 it takes snake_case
176
+ # keywords and reports them in `inspect.signature` itself.
177
+ return value
302
178
 
303
179
 
304
180
  def _resolve(kotlin, name: str):
@@ -320,7 +196,7 @@ def _resolve(kotlin, name: str):
320
196
  nested = importlib.import_module(kotlin.__name__ + "." + name)
321
197
  except ImportError:
322
198
  return None
323
- return KotlinObject(nested), True
199
+ return _kotlin_object(nested), True
324
200
  return None
325
201
 
326
202
 
@@ -400,6 +276,25 @@ class KotlinObject:
400
276
  return f"<pythonx view of Kotlin object {self._kotlin.__name__}>"
401
277
 
402
278
 
279
+ class CallableKotlinObject(KotlinObject):
280
+ """A Kotlin object whose name is also a function in its package (`Color`), callable as that function.
281
+
282
+ The binder makes such a module callable (python-multiplatform #78): `Color(0xFFFFFFFF)` calls
283
+ the `Color` function, while `Color.Red` is still a constant of the object. Calling goes to the
284
+ binder's module itself, which resolves the function on every call.
285
+ """
286
+
287
+ __slots__ = ()
288
+
289
+ def __call__(self, *args, **kwargs):
290
+ return self._kotlin(*args, **kwargs)
291
+
292
+
293
+ def _kotlin_object(kotlin_module):
294
+ """The namespace for a Kotlin object module: callable only when the binder made the module callable."""
295
+ return CallableKotlinObject(kotlin_module) if callable(kotlin_module) else KotlinObject(kotlin_module)
296
+
297
+
403
298
  class ConstantGroup:
404
299
  """The constants of a Kotlin object declared as one type nested in it: `Alignment.Horizontal`.
405
300
 
@@ -1,4 +1,4 @@
1
- # GENERATED by scripts/gen_stubs.py from python-multiplatform's Kotlin-named stubs (artifact kotlin-stubs, workflow run 37103737430, commit a5028618, Compose 1.11.1). Do not edit.
1
+ # GENERATED by scripts/gen_stubs.py from python-multiplatform's Kotlin-named stubs (artifact kotlin-stubs, workflow run 37131041879, commit 452cc807, Compose 1.11.1). Do not edit.
2
2
  import typing as _t
3
3
 
4
4
  class BorderStroke:
@@ -1,2 +1,2 @@
1
- # GENERATED by scripts/gen_stubs.py from python-multiplatform's Kotlin-named stubs (artifact kotlin-stubs, workflow run 37103737430, commit a5028618, Compose 1.11.1). Do not edit.
1
+ # GENERATED by scripts/gen_stubs.py from python-multiplatform's Kotlin-named stubs (artifact kotlin-stubs, workflow run 37131041879, commit 452cc807, Compose 1.11.1). Do not edit.
2
2
  from pythonx.compose.layout import *
@@ -1,4 +1,4 @@
1
- # GENERATED by scripts/gen_stubs.py from python-multiplatform's Kotlin-named stubs (artifact kotlin-stubs, workflow run 37103737430, commit a5028618, Compose 1.11.1). Do not edit.
1
+ # GENERATED by scripts/gen_stubs.py from python-multiplatform's Kotlin-named stubs (artifact kotlin-stubs, workflow run 37131041879, commit 452cc807, Compose 1.11.1). Do not edit.
2
2
  import typing as _t
3
3
 
4
4
  class _TextFieldState_clearText(_t.Protocol):
@@ -30,7 +30,7 @@ class TextFieldLineLimits:
30
30
 
31
31
  class TextFieldState:
32
32
  """Kotlin: androidx.compose.foundation.text.input.TextFieldState"""
33
- def __init__(self, initialText: str = ..., initialSelection: _t.Any = ...) -> None:
33
+ def __init__(self, initial_text: str = ..., initial_selection: _t.Any = ...) -> None:
34
34
  """Kotlin constructor: androidx.compose.foundation.text.input.TextFieldState (androidx.compose.foundation.text.input.TextFieldState(initialText: kotlin.String, initialSelection: androidx.compose.ui.text.TextRange): androidx.compose.foundation.text.input.TextFieldState)"""
35
35
  ...
36
36
  clear_text: _t.ClassVar[_TextFieldState_clearText]
@@ -1,9 +1,19 @@
1
- # GENERATED by scripts/gen_stubs.py from python-multiplatform's Kotlin-named stubs (artifact kotlin-stubs, workflow run 37103737430, commit a5028618, Compose 1.11.1). Do not edit.
1
+ # GENERATED by scripts/gen_stubs.py from python-multiplatform's Kotlin-named stubs (artifact kotlin-stubs, workflow run 37131041879, commit 452cc807, Compose 1.11.1). Do not edit.
2
2
  import typing as _t
3
3
  import pythonx.compose.material3
4
4
  import pythonx.compose.ui
5
5
  import pythonx.compose.ui.unit
6
6
 
7
+ class _PaddingValues_callable_module(_t.Protocol):
8
+ """Kotlin: the function PaddingValues, and the members of the module PaddingValues"""
9
+ @_t.overload
10
+ def __call__(self, all: float) -> _t.Any: ...
11
+ @_t.overload
12
+ def __call__(self, horizontal: float = ..., vertical: float = ...) -> _t.Any: ... # type: ignore[overload-cannot-match]
13
+ @_t.overload
14
+ def __call__(self, start: float = ..., top: float = ..., end: float = ..., bottom: float = ...) -> _t.Any: ... # type: ignore[overload-cannot-match]
15
+ Zero: _t.Any
16
+
7
17
  class _RowScope_NavigationBarItem(_t.Protocol):
8
18
  def __call__(self, selected: bool, on_click: _t.Callable[[], None], icon: _t.Callable[[], None], modifier: pythonx.compose.ui.Modifier = ..., enabled: bool = ..., label: _t.Callable[[], None] | None = ..., always_show_label: bool = ..., colors: pythonx.compose.material3.NavigationBarItemColors = ..., interaction_source: _t.Any | None = ...) -> None: ...
9
19
 
@@ -154,7 +164,7 @@ class IntrinsicSize:
154
164
 
155
165
  class MutableWindowInsets:
156
166
  """Kotlin: androidx.compose.foundation.layout.MutableWindowInsets"""
157
- def __init__(self, initialInsets: _t.Any = ...) -> None:
167
+ def __init__(self, initial_insets: _t.Any = ...) -> None:
158
168
  """Kotlin constructor: androidx.compose.foundation.layout.MutableWindowInsets (androidx.compose.foundation.layout.MutableWindowInsets(initialInsets: androidx.compose.foundation.layout.WindowInsets): androidx.compose.foundation.layout.MutableWindowInsets)"""
159
169
  ...
160
170
  @property
@@ -554,6 +564,8 @@ def wrap_content_width(receiver: pythonx.compose.ui.Modifier, /, align: pythonx.
554
564
  """Kotlin: androidx.compose.ui.Modifier.wrapContentWidth(align: androidx.compose.ui.Alignment.Horizontal, unbounded: kotlin.Boolean): androidx.compose.ui.Modifier"""
555
565
  ...
556
566
 
567
+ PaddingValues: _PaddingValues_callable_module
568
+
557
569
  @_t.overload
558
570
  def Box(modifier: pythonx.compose.ui.Modifier) -> None: ...
559
571
  @_t.overload
@@ -569,13 +581,6 @@ def FlowRow(modifier: pythonx.compose.ui.Modifier = ..., horizontal_arrangement:
569
581
  @_t.overload
570
582
  def FlowRow(modifier: pythonx.compose.ui.Modifier = ..., horizontal_arrangement: Arrangement.Horizontal = ..., vertical_arrangement: Arrangement.Vertical = ..., item_vertical_alignment: pythonx.compose.ui.Alignment.Vertical = ..., max_items_in_each_row: int = ..., max_lines: int = ..., *, content: _t.Callable[[FlowRowScope], None]) -> None: ... # type: ignore[overload-cannot-match]
571
583
 
572
- @_t.overload
573
- def PaddingValues(all: float) -> _t.Any: ...
574
- @_t.overload
575
- def PaddingValues(horizontal: float = ..., vertical: float = ...) -> _t.Any: ... # type: ignore[overload-cannot-match]
576
- @_t.overload
577
- def PaddingValues(start: float = ..., top: float = ..., end: float = ..., bottom: float = ...) -> _t.Any: ... # type: ignore[overload-cannot-match]
578
-
579
584
  @_t.overload
580
585
  def WindowInsets() -> _t.Any: ...
581
586
  @_t.overload
@@ -1 +1 @@
1
- # GENERATED by scripts/gen_stubs.py from python-multiplatform's Kotlin-named stubs (artifact kotlin-stubs, workflow run 37103737430, commit a5028618, Compose 1.11.1). Do not edit.
1
+ # GENERATED by scripts/gen_stubs.py from python-multiplatform's Kotlin-named stubs (artifact kotlin-stubs, workflow run 37131041879, commit 452cc807, Compose 1.11.1). Do not edit.
@@ -1,4 +1,4 @@
1
- # GENERATED by scripts/gen_stubs.py from python-multiplatform's Kotlin-named stubs (artifact kotlin-stubs, workflow run 37103737430, commit a5028618, Compose 1.11.1). Do not edit.
1
+ # GENERATED by scripts/gen_stubs.py from python-multiplatform's Kotlin-named stubs (artifact kotlin-stubs, workflow run 37131041879, commit 452cc807, Compose 1.11.1). Do not edit.
2
2
  import typing as _t
3
3
  import pythonx.compose.ui.graphics.vector
4
4