Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit a596568

Browse filesBrowse files
authored
Use lexopt for argument parsing (#5602)
1 parent bd94d8d commit a596568
Copy full SHA for a596568

File tree

8 files changed

+328
-394
lines changed
Filter options

8 files changed

+328
-394
lines changed

‎Cargo.lock

Copy file name to clipboardExpand all lines: Cargo.lock
+7-26
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎Cargo.toml

Copy file name to clipboardExpand all lines: Cargo.toml
+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ cfg-if = { workspace = true }
3434
log = { workspace = true }
3535
flame = { workspace = true, optional = true }
3636

37-
clap = "2.34"
37+
lexopt = "0.3"
3838
dirs = { package = "dirs-next", version = "2.0.0" }
3939
env_logger = { version = "0.9.0", default-features = false, features = ["atty", "termcolor"] }
4040
flamescope = { version = "0.1.2", optional = true }

‎Lib/test/test_cmd_line.py

Copy file name to clipboardExpand all lines: Lib/test/test_cmd_line.py
-8
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,6 @@ def verify_valid_flag(self, cmd_line):
3838
self.assertNotIn(b'Traceback', err)
3939
return out
4040

41-
# TODO: RUSTPYTHON
42-
@unittest.expectedFailure
4341
def test_help(self):
4442
self.verify_valid_flag('-h')
4543
self.verify_valid_flag('-?')
@@ -82,8 +80,6 @@ def test_optimize(self):
8280
def test_site_flag(self):
8381
self.verify_valid_flag('-S')
8482

85-
# NOTE: RUSTPYTHON version never starts with Python
86-
@unittest.expectedFailure
8783
def test_version(self):
8884
version = ('Python %d.%d' % sys.version_info[:2]).encode("ascii")
8985
for switch in '-V', '--version', '-VV':
@@ -550,8 +546,6 @@ def test_no_stderr(self):
550546
def test_no_std_streams(self):
551547
self._test_no_stdio(['stdin', 'stdout', 'stderr'])
552548

553-
# TODO: RUSTPYTHON
554-
@unittest.expectedFailure
555549
def test_hash_randomization(self):
556550
# Verify that -R enables hash randomization:
557551
self.verify_valid_flag('-R')
@@ -966,8 +960,6 @@ def test_ignore_PYTHONPATH(self):
966960
self.run_ignoring_vars("'{}' not in sys.path".format(path),
967961
PYTHONPATH=path)
968962

969-
# TODO: RUSTPYTHON
970-
@unittest.expectedFailure
971963
def test_ignore_PYTHONHASHSEED(self):
972964
self.run_ignoring_vars("sys.flags.hash_randomization == 1",
973965
PYTHONHASHSEED="0")

‎examples/dis.rs

Copy file name to clipboardExpand all lines: examples/dis.rs
+40-46
Original file line numberDiff line numberDiff line change
@@ -6,67 +6,59 @@
66
/// example usage:
77
/// $ cargo run --release --example dis demo*.py
88
9-
#[macro_use]
10-
extern crate clap;
11-
extern crate env_logger;
129
#[macro_use]
1310
extern crate log;
1411

15-
use clap::{App, Arg};
12+
use lexopt::ValueExt;
1613
use rustpython_compiler as compiler;
1714
use std::error::Error;
1815
use std::fs;
19-
use std::path::Path;
16+
use std::path::{Path, PathBuf};
2017

21-
fn main() {
18+
fn main() -> Result<(), lexopt::Error> {
2219
env_logger::init();
23-
let app = App::new("dis")
24-
.version(crate_version!())
25-
.author(crate_authors!())
26-
.about("Compiles and disassembles python script files for viewing their bytecode.")
27-
.arg(
28-
Arg::with_name("scripts")
29-
.help("Scripts to scan")
30-
.multiple(true)
31-
.required(true),
32-
)
33-
.arg(
34-
Arg::with_name("mode")
35-
.help("The mode to compile the scripts in")
36-
.long("mode")
37-
.short("m")
38-
.default_value("exec")
39-
.possible_values(&["exec", "single", "eval"])
40-
.takes_value(true),
41-
)
42-
.arg(
43-
Arg::with_name("no_expand")
44-
.help(
45-
"Don't expand CodeObject LoadConst instructions to show \
46-
the instructions inside",
47-
)
48-
.long("no-expand")
49-
.short("x"),
50-
)
51-
.arg(
52-
Arg::with_name("optimize")
53-
.help("The amount of optimization to apply to the compiled bytecode")
54-
.short("O")
55-
.multiple(true),
56-
);
57-
let matches = app.get_matches();
5820

59-
let mode = matches.value_of_lossy("mode").unwrap().parse().unwrap();
60-
let expand_code_objects = !matches.is_present("no_expand");
61-
let optimize = matches.occurrences_of("optimize") as u8;
62-
let scripts = matches.values_of_os("scripts").unwrap();
21+
let mut scripts = vec![];
22+
let mut mode = compiler::Mode::Exec;
23+
let mut expand_code_objects = true;
24+
let mut optimize = 0;
25+
26+
let mut parser = lexopt::Parser::from_env();
27+
while let Some(arg) = parser.next()? {
28+
use lexopt::Arg::*;
29+
match arg {
30+
Long("help") | Short('h') => {
31+
let bin_name = parser.bin_name().unwrap_or("dis");
32+
println!(
33+
"usage: {bin_name} <scripts...> [-m,--mode=exec|single|eval] [-x,--no-expand] [-O]"
34+
);
35+
println!(
36+
"Compiles and disassembles python script files for viewing their bytecode."
37+
);
38+
return Ok(());
39+
}
40+
Value(x) => scripts.push(PathBuf::from(x)),
41+
Long("mode") | Short('m') => {
42+
mode = parser
43+
.value()?
44+
.parse_with(|s| s.parse::<compiler::Mode>().map_err(|e| e.to_string()))?
45+
}
46+
Long("no-expand") | Short('x') => expand_code_objects = false,
47+
Short('O') => optimize += 1,
48+
_ => return Err(arg.unexpected()),
49+
}
50+
}
51+
52+
if scripts.is_empty() {
53+
return Err("expected at least one argument".into());
54+
}
6355

6456
let opts = compiler::CompileOpts {
6557
optimize,
6658
..Default::default()
6759
};
6860

69-
for script in scripts.map(Path::new) {
61+
for script in &scripts {
7062
if script.exists() && script.is_file() {
7163
let res = display_script(script, mode, opts.clone(), expand_code_objects);
7264
if let Err(e) = res {
@@ -76,6 +68,8 @@ fn main() {
7668
eprintln!("{script:?} is not a file.");
7769
}
7870
}
71+
72+
Ok(())
7973
}
8074

8175
fn display_script(

‎examples/parse_folder.rs

Copy file name to clipboardExpand all lines: examples/parse_folder.rs
+7-17
Original file line numberDiff line numberDiff line change
@@ -4,38 +4,28 @@
44
///
55
/// example usage:
66
/// $ RUST_LOG=info cargo run --release parse_folder /usr/lib/python3.7
7-
8-
#[macro_use]
9-
extern crate clap;
107
extern crate env_logger;
118
#[macro_use]
129
extern crate log;
1310

14-
use clap::{App, Arg};
1511
use rustpython_parser::{Parse, ast};
1612
use std::{
17-
path::Path,
13+
path::{Path, PathBuf},
1814
time::{Duration, Instant},
1915
};
2016

2117
fn main() {
2218
env_logger::init();
23-
let app = App::new("parse_folders")
24-
.version(crate_version!())
25-
.author(crate_authors!())
26-
.about("Walks over all .py files in a folder, and parses them.")
27-
.arg(
28-
Arg::with_name("folder")
29-
.help("Folder to scan")
30-
.required(true),
31-
);
32-
let matches = app.get_matches();
3319

34-
let folder = Path::new(matches.value_of("folder").unwrap());
20+
let folder: PathBuf = std::env::args_os()
21+
.nth(1)
22+
.expect("please pass a path argument")
23+
.into();
24+
3525
if folder.exists() && folder.is_dir() {
3626
println!("Parsing folder of python code: {folder:?}");
3727
let t1 = Instant::now();
38-
let parsed_files = parse_folder(folder).unwrap();
28+
let parsed_files = parse_folder(&folder).unwrap();
3929
let t2 = Instant::now();
4030
let results = ScanResult {
4131
t1,

‎src/lib.rs

Copy file name to clipboardExpand all lines: src/lib.rs
+8-5
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,6 @@
3737
//! it will have your modules loaded into the vm.
3838
#![allow(clippy::needless_doctest_main)]
3939

40-
#[macro_use]
41-
extern crate clap;
42-
extern crate env_logger;
4340
#[macro_use]
4441
extern crate log;
4542

@@ -57,7 +54,7 @@ use std::process::ExitCode;
5754

5855
pub use interpreter::InterpreterConfig;
5956
pub use rustpython_vm as vm;
60-
pub use settings::{InstallPipMode, RunMode, opts_with_clap};
57+
pub use settings::{InstallPipMode, RunMode, parse_opts};
6158
pub use shell::run_shell;
6259

6360
/// The main cli of the `rustpython` interpreter. This function will return `std::process::ExitCode`
@@ -73,7 +70,13 @@ pub fn run(init: impl FnOnce(&mut VirtualMachine) + 'static) -> ExitCode {
7370
};
7471
}
7572

76-
let (settings, run_mode) = opts_with_clap();
73+
let (settings, run_mode) = match parse_opts() {
74+
Ok(x) => x,
75+
Err(e) => {
76+
println!("{e}");
77+
return ExitCode::FAILURE;
78+
}
79+
};
7780

7881
// don't translate newlines (\r\n <=> \n)
7982
#[cfg(windows)]

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.