##// END OF EJS Templates
hgweb: encode WSGI environment using the ISO-8859-1 codec...
hgweb: encode WSGI environment using the ISO-8859-1 codec The WSGI specification (PEP 3333) specifies that on Python 3 all strings passed by the server must be of type str with code points encodable using the ISO 8859-1 codec. For some reason, I introduced a bug in 2632c1ed8f34 by applying the reverse change. Maybe I got confused because PEP 3333 says that arbitrary operating system environment variables may be contained in the WSGI environment and therefore we need to handle the WSGI environment variables like we would handle operating system environment variables. The bug mentioned in the previous paragraph and fixed by this changeset manifested e.g. in the path of the URL being encoded in the wrong way. Browsers encode non-ASCII bytes with the percent-encoding. WSGI servers will decode the percent-encoded bytes and pass them to the application as strings where each byte is mapped to the corresponding code point with the same ordinal (i.e. it is decoded using the ISO-8859-1 codec). Mercurial uses the bytes type for these strings (which makes much more sense), so we need to encode it again using the ISO-8859-1 codec. If we use another codec, it can result in nonsense.

File last commit:

r50809:58074252 default
r51713:9ed281bb stable
Show More
item.rs
251 lines | 6.7 KiB | application/rls-services+xml | RustLexer
Simon Sapin
rust: Add Python bindings for DirstateEntry as rustext.dirstate.DirstateItem...
r48857 use cpython::exc;
dirstate: add a concept of "fallback" flags to dirstate item...
r49068 use cpython::ObjectProtocol;
Simon Sapin
rust: Add Python bindings for DirstateEntry as rustext.dirstate.DirstateItem...
r48857 use cpython::PyBytes;
use cpython::PyErr;
use cpython::PyNone;
use cpython::PyObject;
use cpython::PyResult;
use cpython::Python;
use cpython::PythonObject;
use hg::dirstate::DirstateEntry;
Raphaël Gomès
rust-dirstate: introduce intermediate struct for dirstate-v2 data...
r49991 use hg::dirstate::DirstateV2Data;
Simon Sapin
dirstate: store mtimes with nanosecond precision in memory...
r49079 use hg::dirstate::TruncatedTimestamp;
Simon Sapin
rust: Add Python bindings for DirstateEntry as rustext.dirstate.DirstateItem...
r48857 use std::cell::Cell;
py_class!(pub class DirstateItem |py| {
data entry: Cell<DirstateEntry>;
def __new__(
_cls,
wc_tracked: bool = false,
p1_tracked: bool = false,
dirstate-item: change the internal storage and constructor value...
r48950 p2_info: bool = false,
has_meaningful_data: bool = true,
has_meaningful_mtime: bool = true,
dirstate-item: add a "second_ambiguous` flag in the mtime tuple...
r49227 parentfiledata: Option<(u32, u32, Option<(u32, u32, bool)>)> = None,
dirstate: make DirstateItem constructor accept fallback value...
r49069 fallback_exec: Option<bool> = None,
fallback_symlink: Option<bool> = None,
Simon Sapin
rust: Add Python bindings for DirstateEntry as rustext.dirstate.DirstateItem...
r48857
) -> PyResult<DirstateItem> {
dirstate-item: change the internal storage and constructor value...
r48950 let mut mode_size_opt = None;
let mut mtime_opt = None;
if let Some((mode, size, mtime)) = parentfiledata {
if has_meaningful_data {
mode_size_opt = Some((mode, size))
}
if has_meaningful_mtime {
dirstate-item: allow mtime to be None in "parentdata"...
r49201 if let Some(m) = mtime {
mtime_opt = Some(timestamp(py, m)?);
}
dirstate-item: change the internal storage and constructor value...
r48950 }
}
Raphaël Gomès
rust-dirstate: introduce intermediate struct for dirstate-v2 data...
r49991 let entry = DirstateEntry::from_v2_data(DirstateV2Data {
Raphaël Gomès
rust: run `cargo clippy`...
r50809 wc_tracked,
dirstate: make DirstateItem constructor accept fallback value...
r49069 p1_tracked,
p2_info,
Raphaël Gomès
rust-dirstate: introduce intermediate struct for dirstate-v2 data...
r49991 mode_size: mode_size_opt,
mtime: mtime_opt,
dirstate: make DirstateItem constructor accept fallback value...
r49069 fallback_exec,
fallback_symlink,
Raphaël Gomès
rust-dirstate: introduce intermediate struct for dirstate-v2 data...
r49991 });
Simon Sapin
rust: Add Python bindings for DirstateEntry as rustext.dirstate.DirstateItem...
r48857 DirstateItem::create_instance(py, Cell::new(entry))
}
@property
def state(&self) -> PyResult<PyBytes> {
let state_byte: u8 = self.entry(py).get().state().into();
Ok(PyBytes::new(py, &[state_byte]))
}
@property
def mode(&self) -> PyResult<i32> {
Ok(self.entry(py).get().mode())
}
@property
def size(&self) -> PyResult<i32> {
Ok(self.entry(py).get().size())
}
@property
def mtime(&self) -> PyResult<i32> {
Ok(self.entry(py).get().mtime())
}
@property
dirstate: add a concept of "fallback" flags to dirstate item...
r49068 def has_fallback_exec(&self) -> PyResult<bool> {
match self.entry(py).get().get_fallback_exec() {
Some(_) => Ok(true),
None => Ok(false),
}
}
@property
def fallback_exec(&self) -> PyResult<Option<bool>> {
match self.entry(py).get().get_fallback_exec() {
Some(exec) => Ok(Some(exec)),
None => Ok(None),
}
}
@fallback_exec.setter
def set_fallback_exec(&self, value: Option<PyObject>) -> PyResult<()> {
match value {
None => {self.entry(py).get().set_fallback_exec(None);},
Some(value) => {
if value.is_none(py) {
self.entry(py).get().set_fallback_exec(None);
} else {
self.entry(py).get().set_fallback_exec(
Some(value.is_true(py)?)
);
}},
}
Ok(())
}
@property
def has_fallback_symlink(&self) -> PyResult<bool> {
match self.entry(py).get().get_fallback_symlink() {
Some(_) => Ok(true),
None => Ok(false),
}
}
@property
def fallback_symlink(&self) -> PyResult<Option<bool>> {
match self.entry(py).get().get_fallback_symlink() {
Some(symlink) => Ok(Some(symlink)),
None => Ok(None),
}
}
@fallback_symlink.setter
def set_fallback_symlink(&self, value: Option<PyObject>) -> PyResult<()> {
match value {
None => {self.entry(py).get().set_fallback_symlink(None);},
Some(value) => {
if value.is_none(py) {
self.entry(py).get().set_fallback_symlink(None);
} else {
self.entry(py).get().set_fallback_symlink(
Some(value.is_true(py)?)
);
}},
}
Ok(())
}
@property
Simon Sapin
rust: Add Python bindings for DirstateEntry as rustext.dirstate.DirstateItem...
r48857 def tracked(&self) -> PyResult<bool> {
Ok(self.entry(py).get().tracked())
}
@property
dirstate-item: introduce a `p1_tracked` property...
r48955 def p1_tracked(&self) -> PyResult<bool> {
Ok(self.entry(py).get().p1_tracked())
}
@property
Simon Sapin
rust: Add Python bindings for DirstateEntry as rustext.dirstate.DirstateItem...
r48857 def added(&self) -> PyResult<bool> {
Ok(self.entry(py).get().added())
}
Raphaël Gomès
dirstate-entry: add `modified` property...
r50715 @property
def modified(&self) -> PyResult<bool> {
Ok(self.entry(py).get().modified())
}
dirstate-item: introduce a `p2_info` property that combine two others...
r48954
@property
def p2_info(&self) -> PyResult<bool> {
Ok(self.entry(py).get().p2_info())
}
Simon Sapin
rust: Add Python bindings for DirstateEntry as rustext.dirstate.DirstateItem...
r48857 @property
def removed(&self) -> PyResult<bool> {
Ok(self.entry(py).get().removed())
}
@property
dirstate-item: introduce a `maybe_clean` property...
r48898 def maybe_clean(&self) -> PyResult<bool> {
Ok(self.entry(py).get().maybe_clean())
}
dirstate-item: introduce a `any_tracked` property...
r48899 @property
def any_tracked(&self) -> PyResult<bool> {
Ok(self.entry(py).get().any_tracked())
}
dirstate-item: add a "second_ambiguous` flag in the mtime tuple...
r49227 def mtime_likely_equal_to(&self, other: (u32, u32, bool))
-> PyResult<bool> {
Simon Sapin
dirstate: store mtimes with nanosecond precision in memory...
r49079 if let Some(mtime) = self.entry(py).get().truncated_mtime() {
Ok(mtime.likely_equal(timestamp(py, other)?))
} else {
Ok(false)
}
}
dirstate-item: implement `drop_merge_data` on the Rust DirstateItem...
r48946 def drop_merge_data(&self) -> PyResult<PyNone> {
self.update(py, |entry| entry.drop_merge_data());
Ok(PyNone)
}
Simon Sapin
rust: Add Python bindings for DirstateEntry as rustext.dirstate.DirstateItem...
r48857 def set_clean(
&self,
Simon Sapin
dirstate-v2: Store unsigned integers inside DirstateEntry...
r49008 mode: u32,
size: u32,
dirstate-item: add a "second_ambiguous` flag in the mtime tuple...
r49227 mtime: (u32, u32, bool),
Simon Sapin
rust: Add Python bindings for DirstateEntry as rustext.dirstate.DirstateItem...
r48857 ) -> PyResult<PyNone> {
Simon Sapin
dirstate: store mtimes with nanosecond precision in memory...
r49079 let mtime = timestamp(py, mtime)?;
Simon Sapin
rust: Add Python bindings for DirstateEntry as rustext.dirstate.DirstateItem...
r48857 self.update(py, |entry| entry.set_clean(mode, size, mtime));
Ok(PyNone)
}
def set_possibly_dirty(&self) -> PyResult<PyNone> {
self.update(py, |entry| entry.set_possibly_dirty());
Ok(PyNone)
}
def set_tracked(&self) -> PyResult<PyNone> {
self.update(py, |entry| entry.set_tracked());
Ok(PyNone)
}
def set_untracked(&self) -> PyResult<PyNone> {
self.update(py, |entry| entry.set_untracked());
Ok(PyNone)
}
});
impl DirstateItem {
pub fn new_as_pyobject(
py: Python<'_>,
entry: DirstateEntry,
) -> PyResult<PyObject> {
Ok(DirstateItem::create_instance(py, Cell::new(entry))?.into_object())
}
Simon Sapin
dirstate: Skip no-op conversion in Rust DirstateMap::set_v1...
r48859 pub fn get_entry(&self, py: Python<'_>) -> DirstateEntry {
self.entry(py).get()
}
Simon Sapin
rust: Add Python bindings for DirstateEntry as rustext.dirstate.DirstateItem...
r48857 // TODO: Use https://doc.rust-lang.org/std/cell/struct.Cell.html#method.update instead when it’s stable
pub fn update(&self, py: Python<'_>, f: impl FnOnce(&mut DirstateEntry)) {
let mut entry = self.entry(py).get();
f(&mut entry);
self.entry(py).set(entry)
}
}
Simon Sapin
dirstate: store mtimes with nanosecond precision in memory...
r49079
pub(crate) fn timestamp(
py: Python<'_>,
dirstate-item: add a "second_ambiguous` flag in the mtime tuple...
r49227 (s, ns, second_ambiguous): (u32, u32, bool),
Simon Sapin
dirstate: store mtimes with nanosecond precision in memory...
r49079 ) -> PyResult<TruncatedTimestamp> {
dirstate-item: add a "second_ambiguous` flag in the mtime tuple...
r49227 TruncatedTimestamp::from_already_truncated(s, ns, second_ambiguous)
.map_err(|_| {
PyErr::new::<exc::ValueError, _>(
py,
"expected mtime truncated to 31 bits",
)
})
Simon Sapin
dirstate: store mtimes with nanosecond precision in memory...
r49079 }