zig-zon 0.0.3__tar.gz → 0.0.4__tar.gz

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.
@@ -7,34 +7,49 @@ const mem = std.mem;
7
7
  pub const CPython = @This();
8
8
 
9
9
  exe: Build.LazyPath,
10
+ version: ?[]const u8 = null,
10
11
 
11
12
  /// adds a `python` option to the build. if not provided, tries to find `python` in PATH
12
- pub fn findAddOption(b: *Build) @This() {
13
- return .{
14
- .exe = b.option(
15
- Build.LazyPath,
16
- "python",
17
- "path to the cpython interpreter executable",
18
- ) orelse {
19
- return find(b);
20
- },
21
- };
13
+ pub fn findAddOption(b: *Build) *CPython {
14
+ if (b.option(
15
+ Build.LazyPath,
16
+ "python",
17
+ "path to the cpython interpreter executable",
18
+ )) |opt| {
19
+ const self = b.allocator.create(CPython) catch @panic("OOM");
20
+ self.* = .{
21
+ .exe = opt,
22
+ };
23
+ return self;
24
+ } else return find(b);
22
25
  }
23
26
 
24
- pub fn find(b: *Build) @This() {
25
- return .{
27
+ pub fn find(b: *Build) *CPython {
28
+ const self = b.allocator.create(CPython) catch @panic("OOM");
29
+ const exe_path = FindExeWindowsCompat.findProgram(b, &.{
30
+ "python",
31
+ "python3",
32
+ }, &.{}) catch {
33
+ const err_wf = b.addWriteFiles();
34
+ const err_step = b.addFail("finding python failed. please provide a path to the exe using -Dpython=");
35
+ err_wf.step.dependOn(&err_step.step);
36
+ self.* = .{ .exe = err_wf.getDirectory() };
37
+ return self;
38
+ };
39
+ self.* = .{
26
40
  .exe = .{
27
- .cwd_relative = FindExeWindowsCompat.findProgram(b, &.{
28
- "python",
29
- "python3",
30
- }, &.{}) catch {
31
- const err_wf = b.addWriteFiles();
32
- const err_step = b.addFail("finding python failed. please provide a path to the exe using -Dpython=");
33
- err_wf.step.dependOn(&err_step.step);
34
- return .{ .exe = err_wf.getDirectory() };
35
- },
41
+ .cwd_relative = exe_path,
36
42
  },
37
43
  };
44
+ return self;
45
+ }
46
+
47
+ pub fn addVersionOption(self: *CPython, b: *Build, fallback: []const u8) void {
48
+ self.version = b.option(
49
+ []const u8,
50
+ "version",
51
+ "set a version string",
52
+ ) orelse fallback;
38
53
  }
39
54
 
40
55
  pub const LinkOptions = struct {
@@ -46,7 +61,7 @@ pub const LinkOptions = struct {
46
61
  };
47
62
  };
48
63
 
49
- pub fn generateIncludeDir(self: @This(), b: *Build) Build.LazyPath {
64
+ pub fn generateIncludeDir(self: CPython, b: *Build) Build.LazyPath {
50
65
  const extract_link_info = Build.Step.Run.create(b, "python header extraction run");
51
66
  extract_link_info.addFileArg(self.exe);
52
67
  extract_link_info.addFileArg(b.path("src/extract_link_info.py"));
@@ -59,7 +74,7 @@ pub fn installExtLib(b: *Build, lib: *Build.Step.Compile) void {
59
74
  b.getInstallStep().dependOn(&lib_install.step);
60
75
  }
61
76
 
62
- pub fn link(self: @This(), b: *Build, opt: LinkOptions) void {
77
+ pub fn link(self: CPython, b: *Build, opt: LinkOptions) void {
63
78
  const target = Build.ResolvedTarget{
64
79
  .query = .{},
65
80
  .result = opt.lib.rootModuleTarget(),
@@ -73,19 +88,32 @@ pub fn link(self: @This(), b: *Build, opt: LinkOptions) void {
73
88
  .target = target,
74
89
  .link_libc = true,
75
90
  });
91
+ cpython.addIncludePath(python_inc);
92
+
93
+ const wf = b.addWriteFiles();
94
+ const pymod_lp = wf.add("python.zig",
95
+ \\pub const c = @import("c");
96
+ \\pub const version = @embedFile("version.txt");
97
+ );
98
+ const pymod = b.createModule(.{ .root_source_file = pymod_lp });
99
+ pymod.addImport("c", cpython.createModule());
100
+
101
+ _ = wf.add(
102
+ "version.txt",
103
+ if (self.version) |version| version else "",
104
+ );
105
+
76
106
  for (opt.macros) |macro| {
77
107
  cpython.defineCMacro(macro[0], macro[1]);
78
108
  }
79
109
 
80
- cpython.addIncludePath(python_inc);
81
-
82
110
  if (target.result.os.tag == .windows) {
83
111
  opt.lib.root_module.addLibraryPath(python_inc);
84
112
  opt.lib.linkSystemLibrary("python");
85
113
  }
86
114
  opt.lib.root_module.addImport(
87
115
  "cpython",
88
- cpython.createModule(),
116
+ pymod,
89
117
  );
90
118
  }
91
119
 
@@ -98,7 +126,7 @@ pub fn lib_ext_name(b: *Build, lib: *Build.Step.Compile) []const u8 {
98
126
  }
99
127
 
100
128
  pub fn run_test(
101
- self: @This(),
129
+ self: CPython,
102
130
  b: *Build,
103
131
  lib: *Build.Step.Compile,
104
132
  test_py_file: Build.LazyPath,
@@ -112,7 +140,7 @@ pub fn run_test(
112
140
  }),
113
141
  });
114
142
  const run_step = b.addRunArtifact(runner);
115
- const python_ext = writeExtFile(b, lib);
143
+ const python_ext = writeExtensionFile(b, lib);
116
144
  run_step.addFileArg(self.exe);
117
145
  run_step.addDirectoryArg(python_ext.dirname());
118
146
  run_step.addFileArg(test_py_file);
@@ -120,7 +148,7 @@ pub fn run_test(
120
148
  return run_step;
121
149
  }
122
150
 
123
- pub fn writeExtFile(b: *Build, lib: *Build.Step.Compile) Build.LazyPath {
151
+ pub fn writeExtensionFile(b: *Build, lib: *Build.Step.Compile) Build.LazyPath {
124
152
  const ext_lib_name = lib_ext_name(b, lib);
125
153
  const wf = b.addWriteFiles();
126
154
  return wf.addCopyFile(lib.getEmittedBin(), ext_lib_name);
zig_zon-0.0.4/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (Expat)
2
+
3
+ Copyright (c) Zig contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
zig_zon-0.0.4/PKG-INFO ADDED
@@ -0,0 +1,53 @@
1
+ Metadata-Version: 2.4
2
+ Name: zig-zon
3
+ Version: 0.0.4
4
+ Summary: a native cpython extension to parse zig object notation strings
5
+ Author-email: Tobias Simetsreiter <dasimmet@gmail.com>
6
+ Maintainer-email: Tobias Simetsreiter <dasimmet@gmail.com>
7
+ License-Expression: MIT
8
+ Project-URL: Homepage, https://gitlab.com/dasimmet/python-zig-zon
9
+ Project-URL: Issues, https://gitlab.com/dasimmet/python-zig-zon/-/issues
10
+ Keywords: zig,ziglang,zon,cpython
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Programming Language :: Python
13
+ Requires-Python: >=3.8
14
+ Description-Content-Type: text/markdown
15
+
16
+ # Python Zig Zon Parser
17
+
18
+ A native python extension built with zig to parse zig-object-notation strings
19
+ into python objects.
20
+
21
+ On PyPi it is only distributed in source, and built during install.
22
+ It therefore needs to download the `ziglang` python package.
23
+
24
+ # Usage
25
+
26
+ install:
27
+
28
+ ```bash
29
+ python3 -m pip install zig-zon
30
+ ```
31
+
32
+ running:
33
+
34
+ ```python
35
+ import zig_zon
36
+ parsed = zig_zon.parse('.{.allyourcode = .are_belong_to_us, .asd = 123}')
37
+ print(parsed)
38
+ ```
39
+
40
+ or, look at the [test](https://gitlab.com/dasimmet/python-zig-zon/-/blob/main/src/test_zig_zon.py)
41
+
42
+ # Developing
43
+
44
+ as opposed to other solutions, i want to develop using:
45
+
46
+ ```
47
+ zig build test
48
+ ```
49
+
50
+ so this command runs a python script that imports and uses the module
51
+ using the system `python` interpreter found in `PATH`. When the module is built using `pip`,
52
+ zig will get a `-Dpython=` option pointing to the right executable,
53
+ as well as a `-Dversion=` option for the pip package version.
@@ -0,0 +1,38 @@
1
+ # Python Zig Zon Parser
2
+
3
+ A native python extension built with zig to parse zig-object-notation strings
4
+ into python objects.
5
+
6
+ On PyPi it is only distributed in source, and built during install.
7
+ It therefore needs to download the `ziglang` python package.
8
+
9
+ # Usage
10
+
11
+ install:
12
+
13
+ ```bash
14
+ python3 -m pip install zig-zon
15
+ ```
16
+
17
+ running:
18
+
19
+ ```python
20
+ import zig_zon
21
+ parsed = zig_zon.parse('.{.allyourcode = .are_belong_to_us, .asd = 123}')
22
+ print(parsed)
23
+ ```
24
+
25
+ or, look at the [test](https://gitlab.com/dasimmet/python-zig-zon/-/blob/main/src/test_zig_zon.py)
26
+
27
+ # Developing
28
+
29
+ as opposed to other solutions, i want to develop using:
30
+
31
+ ```
32
+ zig build test
33
+ ```
34
+
35
+ so this command runs a python script that imports and uses the module
36
+ using the system `python` interpreter found in `PATH`. When the module is built using `pip`,
37
+ zig will get a `-Dpython=` option pointing to the right executable,
38
+ as well as a `-Dversion=` option for the pip package version.
@@ -7,16 +7,7 @@ pub fn build(b: *Build) void {
7
7
  const target = b.standardTargetOptions(.{});
8
8
  const optimize = b.standardOptimizeOption(.{});
9
9
  const python = CPython.findAddOption(b);
10
-
11
- const exe = b.addExecutable(.{
12
- .name = "zigwheeler",
13
- .root_module = b.addModule("zigwheeler", .{
14
- .root_source_file = b.path("src/zigwheeler.zig"),
15
- .target = target,
16
- .optimize = optimize,
17
- }),
18
- });
19
- b.installArtifact(exe);
10
+ python.addVersionOption(b, @import("build.zig.zon").version);
20
11
 
21
12
  const lib = b.addLibrary(.{
22
13
  .name = "zig_zon",
@@ -35,14 +26,9 @@ pub fn build(b: *Build) void {
35
26
  });
36
27
 
37
28
  const install_test = b.addInstallFile(b.path("src/test_zig_zon.py"), "lib/test_zig_zon.py");
38
- b.default_step.dependOn(&install_test.step);
39
- const run = b.addRunArtifact(exe);
40
- if (b.args) |args| {
41
- run.addArgs(args);
42
- }
43
- b.step("run", "run the wheeler").dependOn(&run.step);
29
+ b.step("install-test", "install the python test script alongside the built modules").dependOn(&install_test.step);
44
30
 
45
- const test_run = python.run_test(b, lib, b.path("src/test_zig_zon.py"));
31
+ const run_test = python.run_test(b, lib, b.path("src/test_zig_zon.py"));
46
32
 
47
- b.step("test", "run the python test script").dependOn(&test_run.step);
33
+ b.step("test", "run the python test script").dependOn(&run_test.step);
48
34
  }
@@ -1,7 +1,7 @@
1
1
  .{
2
2
  .name = .python_zig_zon,
3
3
  .fingerprint = 0x3d332656a3644fc9,
4
- .version = "0.0.3",
4
+ .version = "0.0.4",
5
5
  .minimum_zig_version = "0.15.1",
6
6
  .dependencies = .{},
7
7
  .paths = .{
@@ -0,0 +1,25 @@
1
+ [project]
2
+ name = "zig-zon"
3
+ authors = [{ name = "Tobias Simetsreiter", email = "dasimmet@gmail.com" }]
4
+ maintainers = [{ name = "Tobias Simetsreiter", email = "dasimmet@gmail.com" }]
5
+ description = "a native cpython extension to parse zig object notation strings"
6
+ readme = "README.md"
7
+ requires-python = ">=3.8"
8
+ dynamic = ["version"]
9
+ license = "MIT"
10
+ license-files = ["LICEN[CS]E.*"]
11
+ keywords = ["zig", "ziglang", "zon", "cpython"]
12
+ classifiers = [
13
+ "Development Status :: 4 - Beta",
14
+ "Programming Language :: Python",
15
+ ]
16
+
17
+ [project.urls]
18
+ Homepage = "https://gitlab.com/dasimmet/python-zig-zon"
19
+ Issues = "https://gitlab.com/dasimmet/python-zig-zon/-/issues"
20
+
21
+ [build-system]
22
+ requires = ["setuptools", "setuptools-scm", "ziglang==0.15.1"]
23
+ build-backend = "setuptools.build_meta"
24
+
25
+ [tool.setuptools_scm]
@@ -6,23 +6,22 @@ import os
6
6
  # In this package the setuptools_zig_build cannot be imported as a dependency.
7
7
  # on another package zig_build should be passed to setup()
8
8
  sys.path.insert(0, os.path.normpath(os.path.join(__file__, '..'))) # nopep8
9
- from setuptools_zig_build import ZigBuildExtension # nopep8
9
+ from setuptools_zig_build import ZigBuildExtension, ZigBuild # nopep8
10
10
 
11
- zig_build = {
12
- "use_zig_python_package": True,
13
- "optimize": "ReleaseSmall",
11
+ zig_build = ZigBuild(**{
12
+ "use_ziglang_python_package": True,
13
+ "optimize": "ReleaseSmall", # passes -Doptimize= to zig build
14
+ "pass_version_option": True, # passes -Dversion=<pip package version> to zig build
14
15
  'test_step': 'test', # this is failing on windows for now ;-/
15
- 'extra_args': [],
16
- }
16
+ 'extra_args': [], # extra arguments to zig build
17
+ })
17
18
 
18
19
  setup(
19
20
  name='zig-zon',
21
+ packages=[],
20
22
  cmdclass={
21
23
  'build_ext': ZigBuildExtension(zig_build),
22
24
  },
23
25
  ext_modules=[Extension('zig_zon', [])],
24
- setup_requires=[
25
- "setuptools-scm",
26
- "ziglang==0.15.1",
27
- ],
26
+ setup_requires=[],
28
27
  )
@@ -14,10 +14,43 @@ from setuptools.command.build_ext import build_ext as SetupToolsBuildExt
14
14
  class ZigCompilerError(Exception):
15
15
  """Some compile/link operation failed."""
16
16
 
17
+ class ZigBuild:
18
+ '''the type of the custom "zig_build" argument to setup.py'''
19
+ OPTIMIZE = [
20
+ "Debug",
21
+ "ReleaseSafe",
22
+ "ReleaseFast",
23
+ "ReleaseSmall",
24
+ ]
25
+ def __init__(self,
26
+ use_ziglang_python_package: bool = False,
27
+ optimize: str = "ReleaseSafe",
28
+ pass_version_option: bool = False,
29
+ test_step: str = None,
30
+ extra_args: list = [],
31
+ ):
32
+ assert isinstance(use_ziglang_python_package, bool)
33
+ self.use_ziglang_python_package = use_ziglang_python_package
34
+ assert test_step == None or (isinstance(test_step, str) and not test_step.startswith('-'))
35
+ self.test_step = test_step
36
+ assert optimize == None or (isinstance(optimize, str) and optimize in self.OPTIMIZE)
37
+ self.optimize = optimize
38
+ assert isinstance(pass_version_option, bool)
39
+ self.pass_version_option = pass_version_option
40
+ assert isinstance(extra_args, list)
41
+ for arg in extra_args:
42
+ assert isinstance(arg, str)
43
+ self.extra_args = extra_args
17
44
 
18
45
  class BuildExt(SetupToolsBuildExt):
19
46
  def __init__(self, dist, zig_value):
20
- self._zig_value = zig_value
47
+ if isinstance(zig_value, dict):
48
+ self._zig_value = ZigBuild(**zig_value)
49
+ elif isinstance(zig_value, ZigBuild):
50
+ self._zig_value = zig_value
51
+ else:
52
+ raise ZigCompilerError('unknown type:', zig_value)
53
+
21
54
  super().__init__(dist)
22
55
 
23
56
  def build_extension(self, ext):
@@ -38,34 +71,27 @@ class BuildExt(SetupToolsBuildExt):
38
71
 
39
72
  zig_out = Path(self.build_temp) / "zig-out"
40
73
 
41
- bld_cmd = [os.environ.get('PY_ZIG', 'zig'), 'build', 'install',
42
- '-Dpython={}'.format(sys.executable), '--prefix', str(zig_out.absolute())]
43
-
44
- if isinstance(self._zig_value, dict):
45
- if 'use_zig_python_package' in self._zig_value and self._zig_value['use_zig_python_package'] == True:
46
- import ziglang
47
- bld_cmd[0] = os.path.join(
48
- os.path.dirname(ziglang.__file__), "zig")
49
-
50
- if 'test_step' in self._zig_value:
51
- bld_cmd.append(self._zig_value['test_step'])
52
-
53
- if 'optimize' in self._zig_value:
54
- assert isinstance(self._zig_value['optimize'], str)
55
- assert self._zig_value['optimize'] in [
56
- "Debug",
57
- "ReleaseSafe",
58
- "ReleaseFast",
59
- "ReleaseSmall",
60
- ]
61
- bld_cmd.append(
62
- '-Doptimize={}'.format(self._zig_value['optimize']))
63
-
64
- if 'extra_args' in self._zig_value:
65
- assert isinstance(self._zig_value['extra_args'], list)
66
- for arg in self._zig_value['extra_args']:
67
- assert isinstance(arg, str)
68
- bld_cmd.append(arg)
74
+ zig_exe = os.environ.get('PY_ZIG', 'zig')
75
+ if self._zig_value.use_ziglang_python_package == True:
76
+ import ziglang
77
+ zig_exe = os.path.join(
78
+ os.path.dirname(ziglang.__file__), "zig")
79
+
80
+ bld_cmd = [zig_exe, 'build', 'install',
81
+ '-Dpython={}'.format(sys.executable), '--prefix', str(zig_out.absolute())]
82
+
83
+ if self._zig_value.test_step != None:
84
+ bld_cmd.append(self._zig_value.test_step)
85
+
86
+ if self._zig_value.optimize != None:
87
+ bld_cmd.append(
88
+ '-Doptimize={}'.format(self._zig_value.optimize))
89
+
90
+ if self._zig_value.pass_version_option == True:
91
+ bld_cmd.append(
92
+ '-Dversion={}'.format(self.distribution.get_version()))
93
+
94
+ bld_cmd.extend(self._zig_value.extra_args)
69
95
 
70
96
  os.makedirs(self.build_temp, exist_ok=True)
71
97
  print('\ncmd', shlex.join(bld_cmd))
@@ -102,6 +128,7 @@ class ZigBuildExtension:
102
128
 
103
129
 
104
130
  def setup_build_zig(dist, keyword, value):
131
+ '''our hook into setuptools '''
105
132
  assert isinstance(dist, Distribution)
106
133
  assert keyword == 'build_zig'
107
134
  be = dist.cmdclass.get('build_ext')
@@ -11,10 +11,6 @@ syspath = sysconfig.get_paths()
11
11
  lib_filename = 'python{}{}.lib'.format(
12
12
  sys.version_info.major, sys.version_info.minor)
13
13
 
14
- print("syspath:", syspath, file=sys.stderr)
15
- print("include:", syspath['include'], file=sys.stderr)
16
- print("data:", syspath['data'], file=sys.stderr)
17
-
18
14
  os.makedirs(output_dir, exist_ok=True)
19
15
  shutil.copytree(syspath['include'], output_dir, dirs_exist_ok=True)
20
16
 
@@ -46,9 +42,12 @@ for k, v in sysconfig.get_config_vars().items():
46
42
  lib_paths += vfl
47
43
 
48
44
  if sys.platform == 'windows' and not found_lib:
49
- print("Did not find", lib_filename, "in:")
50
- print(lib_paths)
45
+ print("Warning: Did not find", lib_filename, "in:", file=sys.stderr)
46
+ print(lib_paths, file=sys.stderr)
51
47
 
48
+ python_h = os.path.join(output_dir, 'Python.h')
49
+ if not os.path.isfile(python_h):
50
+ raise Exception("Python.h missing! syspath include: {}\n output: {}".format(syspath['include'], output_dir))
52
51
 
53
52
  with open(os.path.join(output_dir, 'Zig_Python_With_Hexver.h'), 'w') as fd:
54
53
  fd.write('''
@@ -26,6 +26,13 @@ assert testzon['my_hex_int'] == 0xdeadbeef
26
26
  assert testzon['my_negative_int'] == -432_123_111
27
27
  assert testzon['my_negative_big_int'] == -4611686018427387904
28
28
  assert testzon['my_optional'] == None
29
+ assert zig_zon.parse(str(2**63 - 1)) == 2**63 - 1
30
+ assert zig_zon.parse(str(2**63)) == 2**63
31
+ assert zig_zon.parse(str(2**64 - 1)) == 2**64 - 1
32
+
33
+ # print("TODO: 2**64 ==", 2**64, ", zig_zon.parse(str(2**64)) ==",
34
+ # zig_zon.parse(str(2**64)))
35
+ # assert zig_zon.parse(str(2**64)) == str(2**64)
29
36
 
30
37
  print('build.zig.zon:')
31
38
  with open('build.zig.zon') as fd:
@@ -4,7 +4,8 @@ const Allocator = std.mem.Allocator;
4
4
  const assert = std.debug.assert;
5
5
  const ZonGen = std.zig.ZonGen;
6
6
 
7
- const c = @import("cpython");
7
+ const python = @import("cpython");
8
+ const c = python.c;
8
9
  const PyObject = c.PyObject;
9
10
 
10
11
  const PyModuleDef_Base = extern struct {
@@ -15,13 +16,6 @@ const PyModuleDef_Base = extern struct {
15
16
  m_copy: [*c]PyObject = null,
16
17
  };
17
18
 
18
- const PyModuleDef_HEAD_INIT = PyModuleDef_Base{ .ob_base = PyObject{
19
- .unnamed_0 = .{
20
- .ob_refcnt = 1,
21
- },
22
- .ob_type = null,
23
- } };
24
-
25
19
  pub var methods = [_]c.PyMethodDef{
26
20
  c.PyMethodDef{
27
21
  .ml_name = "parse",
@@ -38,7 +32,36 @@ pub var zigmodule = c.PyModuleDef{
38
32
  };
39
33
 
40
34
  pub export fn PyInit_zig_zon() [*c]c.PyObject {
41
- return c.PyModule_Create(&zigmodule);
35
+ const mod = c.PyModule_Create(&zigmodule);
36
+ const semver = std.SemanticVersion.parse(python.version) catch unreachable;
37
+ const version = c.PyDict_New();
38
+
39
+ _ = c.PyDict_SetItemString(version, "major", c.Py_BuildValue("n", semver.major));
40
+ _ = c.PyDict_SetItemString(version, "minor", c.Py_BuildValue("n", semver.minor));
41
+ _ = c.PyDict_SetItemString(version, "patch", c.Py_BuildValue("n", semver.patch));
42
+ if (semver.pre) |pre| {
43
+ _ = c.PyDict_SetItemString(version, "pre", c.Py_BuildValue("s#", pre.ptr, pre.len));
44
+ } else {
45
+ _ = c.PyDict_SetItemString(version, "pre", PyNone());
46
+ }
47
+ if (semver.build) |build| {
48
+ _ = c.PyDict_SetItemString(version, "build", c.Py_BuildValue("s#", build.ptr, build.len));
49
+ } else {
50
+ _ = c.PyDict_SetItemString(version, "build", PyNone());
51
+ }
52
+ _ = c.PyObject_SetAttrString(
53
+ mod,
54
+ "__version__",
55
+ version,
56
+ );
57
+
58
+ const version_str = c.Py_BuildValue("s#", python.version.ptr, python.version.len);
59
+ _ = c.PyObject_SetAttrString(
60
+ mod,
61
+ "__version_str__",
62
+ version_str,
63
+ );
64
+ return mod;
42
65
  }
43
66
 
44
67
  pub fn parse(self: [*]PyObject, args: [*]PyObject) callconv(.c) [*c]PyObject {
@@ -89,6 +112,10 @@ pub fn parse(self: [*]PyObject, args: [*]PyObject) callconv(.c) [*c]PyObject {
89
112
  };
90
113
  }
91
114
 
115
+ inline fn PyNone() [*c]c.PyObject {
116
+ return c.Py_BuildValue("");
117
+ }
118
+
92
119
  const ZonError = error{
93
120
  StructExpected,
94
121
  StructIdentifierExpected,
@@ -143,13 +170,13 @@ fn parseZon(arena: Allocator, tree: Ast, node: Ast.Node.Index) ZonError!*c.PyObj
143
170
  } else if (std.mem.eql(u8, token_slice, "false")) {
144
171
  return c.PyBool_FromLong(@as(c_long, 0));
145
172
  } else if (std.mem.eql(u8, token_slice, "null")) {
146
- return c.Py_BuildValue(""); // c.Py_None()
173
+ return PyNone();
147
174
  } else {
148
175
  if (@errorReturnTrace()) |et| {
149
176
  std.debug.dumpStackTrace(et.*);
150
177
  std.debug.dumpCurrentStackTrace(null);
151
178
  }
152
- std.log.err("not implemented: {any} '{s}'", .{ node_tag, token_slice });
179
+ std.log.err("identifier not implemented: {any} '{s}'", .{ node_tag, token_slice });
153
180
  return error.NotImplemented;
154
181
  }
155
182
  },
@@ -159,7 +186,7 @@ fn parseZon(arena: Allocator, tree: Ast, node: Ast.Node.Index) ZonError!*c.PyObj
159
186
  std.debug.dumpCurrentStackTrace(null);
160
187
  }
161
188
  const token_slice = tree.tokenSlice(tree.firstToken(node));
162
- std.log.err("not implemented: {any} '{s}'", .{ node_tag, token_slice });
189
+ std.log.err("zon ast token not implemented: {any} '{s}'", .{ node_tag, token_slice });
163
190
  return error.NotImplemented;
164
191
  },
165
192
  }
@@ -180,7 +207,13 @@ fn parseNumberLiteral(arena: Allocator, tree: Ast, node: Ast.Node.Index, negated
180
207
  switch (parsed) {
181
208
  .int => |n| {
182
209
  const factor: i64 = if (negated) -1 else 1;
183
- return c.Py_BuildValue("n", factor * @as(i64, @bitCast(n)));
210
+ const neglim = 9223372036854775807; // 2**63 - 1
211
+ if (n <= neglim) {
212
+ return c.PyLong_FromSsize_t(factor * @as(i64, @intCast(n)));
213
+ } else {
214
+ if (factor == -1) return error.BigIntNotImplemented;
215
+ return c.PyLong_FromSize_t(n);
216
+ }
184
217
  },
185
218
  .big_int => return error.BigIntNotImplemented,
186
219
  .float => |n| {
@@ -0,0 +1,53 @@
1
+ Metadata-Version: 2.4
2
+ Name: zig-zon
3
+ Version: 0.0.4
4
+ Summary: a native cpython extension to parse zig object notation strings
5
+ Author-email: Tobias Simetsreiter <dasimmet@gmail.com>
6
+ Maintainer-email: Tobias Simetsreiter <dasimmet@gmail.com>
7
+ License-Expression: MIT
8
+ Project-URL: Homepage, https://gitlab.com/dasimmet/python-zig-zon
9
+ Project-URL: Issues, https://gitlab.com/dasimmet/python-zig-zon/-/issues
10
+ Keywords: zig,ziglang,zon,cpython
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Programming Language :: Python
13
+ Requires-Python: >=3.8
14
+ Description-Content-Type: text/markdown
15
+
16
+ # Python Zig Zon Parser
17
+
18
+ A native python extension built with zig to parse zig-object-notation strings
19
+ into python objects.
20
+
21
+ On PyPi it is only distributed in source, and built during install.
22
+ It therefore needs to download the `ziglang` python package.
23
+
24
+ # Usage
25
+
26
+ install:
27
+
28
+ ```bash
29
+ python3 -m pip install zig-zon
30
+ ```
31
+
32
+ running:
33
+
34
+ ```python
35
+ import zig_zon
36
+ parsed = zig_zon.parse('.{.allyourcode = .are_belong_to_us, .asd = 123}')
37
+ print(parsed)
38
+ ```
39
+
40
+ or, look at the [test](https://gitlab.com/dasimmet/python-zig-zon/-/blob/main/src/test_zig_zon.py)
41
+
42
+ # Developing
43
+
44
+ as opposed to other solutions, i want to develop using:
45
+
46
+ ```
47
+ zig build test
48
+ ```
49
+
50
+ so this command runs a python script that imports and uses the module
51
+ using the system `python` interpreter found in `PATH`. When the module is built using `pip`,
52
+ zig will get a `-Dpython=` option pointing to the right executable,
53
+ as well as a `-Dversion=` option for the pip package version.
@@ -1,4 +1,5 @@
1
1
  CPython.zig
2
+ LICENSE
2
3
  MANIFEST.in
3
4
  README.md
4
5
  build.zig
@@ -11,7 +12,7 @@ src/python-runner.zig
11
12
  src/test_zig_zon.py
12
13
  src/zig_zon.zig
13
14
  src/zigwheeler.zig
14
- src/zig_zon.egg-info/PKG-INFO
15
- src/zig_zon.egg-info/SOURCES.txt
16
- src/zig_zon.egg-info/dependency_links.txt
17
- src/zig_zon.egg-info/top_level.txt
15
+ zig_zon.egg-info/PKG-INFO
16
+ zig_zon.egg-info/SOURCES.txt
17
+ zig_zon.egg-info/dependency_links.txt
18
+ zig_zon.egg-info/top_level.txt
@@ -0,0 +1 @@
1
+ zig_zon
zig_zon-0.0.3/PKG-INFO DELETED
@@ -1,30 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: zig-zon
3
- Version: 0.0.3
4
- Summary: My package description
5
- Author-email: Tobias Simetsreiter <dasimmet@gmail.com>
6
- Requires-Python: >=3.8
7
- Description-Content-Type: text/markdown
8
-
9
- # Python Zig Zon Parser
10
-
11
- A native python extension built with zig to parse zig-object-notation strings
12
- into python objects.
13
-
14
- # Usage (so far only linux)
15
-
16
- install:
17
-
18
- ```bash
19
- python3 -m pip install git+https://gitlab.com/dasimmet/python-zig-zon.git
20
- ```
21
-
22
- running:
23
-
24
- ```python
25
- import zig_zon
26
- parsed = zig_zon.parse('.{.allyourcode = .are_belong_to_us, .asd = 123}')
27
- print(parsed)
28
- ```
29
-
30
- or, look at the [test](test.py)
zig_zon-0.0.3/README.md DELETED
@@ -1,22 +0,0 @@
1
- # Python Zig Zon Parser
2
-
3
- A native python extension built with zig to parse zig-object-notation strings
4
- into python objects.
5
-
6
- # Usage (so far only linux)
7
-
8
- install:
9
-
10
- ```bash
11
- python3 -m pip install git+https://gitlab.com/dasimmet/python-zig-zon.git
12
- ```
13
-
14
- running:
15
-
16
- ```python
17
- import zig_zon
18
- parsed = zig_zon.parse('.{.allyourcode = .are_belong_to_us, .asd = 123}')
19
- print(parsed)
20
- ```
21
-
22
- or, look at the [test](test.py)
@@ -1,13 +0,0 @@
1
- [project]
2
- name = "zig-zon"
3
- authors = [{ name = "Tobias Simetsreiter", email = "dasimmet@gmail.com" }]
4
- description = "My package description"
5
- readme = "README.md"
6
- requires-python = ">=3.8"
7
- dynamic = ["version"]
8
-
9
- [build-system]
10
- requires = ["setuptools"]
11
- build-backend = "setuptools.build_meta"
12
-
13
- [tool.setuptools_scm]
@@ -1,30 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: zig-zon
3
- Version: 0.0.3
4
- Summary: My package description
5
- Author-email: Tobias Simetsreiter <dasimmet@gmail.com>
6
- Requires-Python: >=3.8
7
- Description-Content-Type: text/markdown
8
-
9
- # Python Zig Zon Parser
10
-
11
- A native python extension built with zig to parse zig-object-notation strings
12
- into python objects.
13
-
14
- # Usage (so far only linux)
15
-
16
- install:
17
-
18
- ```bash
19
- python3 -m pip install git+https://gitlab.com/dasimmet/python-zig-zon.git
20
- ```
21
-
22
- running:
23
-
24
- ```python
25
- import zig_zon
26
- parsed = zig_zon.parse('.{.allyourcode = .are_belong_to_us, .asd = 123}')
27
- print(parsed)
28
- ```
29
-
30
- or, look at the [test](test.py)
@@ -1,3 +0,0 @@
1
- extract_link_info
2
- test_zig_zon
3
- zig_zon
File without changes
File without changes
File without changes
File without changes