Skip to content

Commit 04c32a1

Browse files
committed
feat(Lib/sys): flags
1 parent 5d0659d commit 04c32a1

File tree

4 files changed

+132
-0
lines changed

4 files changed

+132
-0
lines changed

src/pylib/Lib/n_sys.nim

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ impExp sys_impl,
1717
exits,
1818
getencodings,
1919
sizes,
20+
flagsImpl,
2021
auditImpl
2122
2223

src/pylib/Lib/sys_impl/flagsImpl.nim

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
2+
3+
import ./flagsImpl/values
4+
5+
genFlagsObj()
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
## `PYTHON*` environment variables will be loaded iif pylibUsePyEnv is defined.
2+
import ../../../version
3+
import std/macros
4+
#[
5+
import std/macrocache
6+
const fields = CacheSeq"sys.flags-fields"
7+
export macrocache
8+
]#
9+
var fields*{.compileTime.} = newSeqOfCap[NimNode](18)
10+
11+
template addField(f) =
12+
static:
13+
const fname = astToStr(f)
14+
fields.add ident fname
15+
16+
template toCfgName(f): string = "pylibConfig" & astToStr(f)
17+
template flag(f; defval=false) =
18+
const f*{.booldefine: f.toCfgName.} = defval
19+
addField f
20+
21+
template flagi(f; defval=0) =
22+
const f*{.intdefine: f.toCfgName.} = defval
23+
addField f
24+
25+
const PY_LONG_DEFAULT_MAX_STR_DIGITS = 4300 ## PY-DIFF: no use (PyLong is not implemented)
26+
27+
# Following defvals are according to Python/initconfig.c:_PyConfig_Read `if (config->isolated) {...`
28+
flagi debug, int(not defined(release))
29+
flagi inspect
30+
flagi interactive
31+
pysince(3,4): flagi isolated
32+
flagi optimize, defined(release).int + defined(danger).int
33+
flagi dont_write_bytecode, 1 ## PY_DIFF: default is 1, as we doesn't produce .pyc
34+
flagi no_user_site, isolated
35+
flagi no_site
36+
flagi ignore_environment, int(defined(pylibUsePyEnv) or bool isolated) ## PY-DIFF: we ignore `PYTHON*` env by default
37+
flagi verbose
38+
flagi bytes_warning
39+
pysince(3,2): flagi quiet
40+
flagi hash_randomization
41+
pysince(3,7): flag dev_mode
42+
flagi utf8_mode
43+
pysince(3,11): flag safe_path, isolated!=0
44+
pysince(3,11): flagi int_max_str_digits, PY_LONG_DEFAULT_MAX_STR_DIGITS
45+
pysince(3,10): flagi warn_default_encoding
46+
47+
48+
macro redefineFlags*(kws: varargs[untyped]) =
49+
## used in intermediate file, which wanna define some runtime flags.
50+
## due to `export except`'s behavior, unknown kws are just ignored.
51+
result = newStmtList()
52+
var exp = nnkExportExceptStmt.newTree ident"ct"
53+
for kw in kws:
54+
exp.add kw[0]
55+
result.add newLetStmt(
56+
kw[0].postfix"*", kw[1]
57+
)
58+
result.add exp
59+
60+
macro genFlagsObj* =
61+
## generate `let flags* = ...`
62+
var ntup = newNimNode nnkTupleConstr
63+
for f in ct.fields:
64+
let val = ident(f.strVal)
65+
ntup.add nnkExprColonExpr.newTree(
66+
f, val
67+
)
68+
result = newLetStmt(ident("flags").postfix"*", ntup)
69+
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
2+
3+
import ./ct
4+
when ignore_environment == 0:
5+
#const use_environment = true
6+
import std/macros
7+
import ../../../Python/config_read_env
8+
var call{.compileTime.} = newCall("redefineFlags")
9+
proc envImpl(name, fn, envName: NimNode): NimNode =
10+
call.add nnkExprEqExpr.newTree(name,
11+
newCall(fn,
12+
envName,
13+
name)
14+
)
15+
result = newEmptyNode()
16+
17+
macro env(fn; name) = envImpl(name, fn, newCall("toPyEnv", newLit name.strVal))
18+
macro env(fn; name; envName) = envImpl(name, fn, envName)
19+
template envE(name) = env ib_e , name
20+
template envI(name) = env ib_i, name
21+
template envB(name) = env ib_b, name
22+
23+
# Python/initconfig.c:config_read_env_vars
24+
envI debug
25+
envI verbose
26+
envI optimize
27+
envI inspect
28+
29+
envB dont_write_bytecode
30+
envB no_user_site
31+
32+
envE safe_path
33+
34+
# Python/initconfig.c:config_read_complex_options ->
35+
# Python/initconfig.c:config_init_int_max_str_digits
36+
envI int_max_str_digits
37+
38+
# Python/preconfig.c:preconfig_init_utf8_mode
39+
env ib_i, utf8_mode, "PYTHONUTF8" # XXX: PY-DIFF: python will crash if PYTHONUTF8 is neither 0 nor 1
40+
41+
# Python/preconfig.c:_PyPreCmdline_Read
42+
envE dev_mode
43+
#[
44+
XXX: PY-BUG: as of v3.14.0a7, https://docs.python.org/3/library/devmode.html#devmode says
45+
"setting the PYTHONDEVMODE environment variable to 1."
46+
but it's just implemented as checking existence of PYTHONDEVMODE, whatever it's set: 0, -1 ,etc
47+
]#
48+
envE warn_default_encoding
49+
50+
macro genCall = call
51+
genCall()
52+
53+
#[
54+
const PY_LONG_DEFAULT_MAX_STR_DIGITS =
55+
len $high(int)
56+
## 4300 ## PY-DIFF: no use (PyLong is not implemented)
57+
]#

0 commit comments

Comments
 (0)