Commit Graph

55 Commits

Author SHA1 Message Date
Jun Wu
4e7987e9f9 cpython-ext: avoid io::Error::raw_os_error unless kind is None
Summary:
On Windows, EPIPE's raw os error might be 232, different from libc::EPIPE (32).
That means the Python world cannot check the errno properly to hide the EPIPE
error message. Fix it by reading io::ErrorKind first, and fallback to
raw_os_error.

Reviewed By: yancouto

Differential Revision: D30118006

fbshipit-source-id: b34a2142b24714e68d11a03a0771a5f9c037ed0f
2021-08-05 16:32:50 -07:00
Jun Wu
8bc4d6e3fb cpython-ext: rename pycell to PyCell
Summary:
cpython-ext is not part of hg business APIs. It does not need to be consistent
with lower-case class name (and hg codebase is okay with non-lowercase class names,
just that most classes there are lower-case).

This resolves a rustc warning about the struct name.

Reviewed By: kulshrax

Differential Revision: D29526579

fbshipit-source-id: a4bc8e788d55c65aae9eaa87e2c684c2fded7ae2
2021-07-06 13:16:10 -07:00
Jun Wu
80714c8647 lib: remove most rustc warnings
Summary: The warnings make build output less clean.

Reviewed By: kulshrax

Differential Revision: D29526580

fbshipit-source-id: eb4069c2edd111bb04b8754e7051035b8aa8a508
2021-07-01 18:08:55 -07:00
Andrey Chursin
0e56fa056f cpython_ext: add pycell::import
Summary: The use case here is that we can export rust struct into python object, manipulate python object and then convert it back into rust struct

Reviewed By: quark-zju

Differential Revision: D29525281

fbshipit-source-id: 393c8a430a76c720c155432d732085892d56521a
2021-07-01 17:32:13 -07:00
Andrey Chursin
3360815092 cpython-ext: add method to export pycell into inspectable python object
Reviewed By: quark-zju

Differential Revision: D29521113

fbshipit-source-id: ff5c0be50149262d555105e495633847059a78a6
2021-07-01 16:11:48 -07:00
Andrey Chursin
6b649ab8e2 cpython-ext: conditionally derive traits for Serde
Summary:
Previously Serde<T> required T to implement bunch of traits like Eq, Clone etc

This diff lifts this restriction and only implements those traits for Serde if T implements them, but does not require them

Reviewed By: quark-zju

Differential Revision: D29521112

fbshipit-source-id: e9387b08ab129fc1f2450f6c88fa7fe0f6451349
2021-07-01 16:11:48 -07:00
Andrey Chursin
910e457673 cpython_ext: introduce pycell
Summary:
We currently encode/decode data when passing it between pull_fast_forward_master and importpulldata and some other cases
pycell is alternative to that, allowing to just transfer pointer, instead of encoding data

Reviewed By: quark-zju

Differential Revision: D29474444

fbshipit-source-id: aabbbb670fde08645031c199afbdeab5cc9093d8
2021-07-01 10:49:01 -07:00
Davide Cavalca
b82c5672fc Update several rust crate versions
Summary: Update versions for several of the crates we depend on.

Reviewed By: danobi

Differential Revision: D29165283

fbshipit-source-id: baaa9fa106b7dad000f93d2eefa95867ac46e5a1
2021-06-17 16:38:19 -07:00
Jun Wu
1dd14a9cf4 io: add ways to test if a stream is a std stream
Summary: This will be used later.

Reviewed By: skotchvail

Differential Revision: D27744058

fbshipit-source-id: 411ab66ccc38b306c6bffb190e936ba1e455f07a
2021-04-13 13:43:39 -07:00
Alex Hornby
617489bdc5 eden/scm/lib: default to python3-sys
Summary:
eden/scm/lib: default cpython_ext to python3
```

CI internally,  try a PR on github once its landed.

Reviewed By: quark-zju

Differential Revision: D27237636

fbshipit-source-id: 1768f778d75b5d6c62dfd5641f911604a37d3163
2021-03-23 01:13:08 -07:00
Lukas Piatkowski
ad106958f2 eden/scm/lib: autogenerate all Cargo.toml files with autocargo
Summary: This diff removes the split between manually managed and autocargo managed Cargo.toml files in `eden/scm/lib`, now all files are autogenerated.

Reviewed By: quark-zju

Differential Revision: D26830884

fbshipit-source-id: 3a5d8409a61347c7650cc7d8192fa426c03733dc
2021-03-05 04:29:49 -08:00
Jun Wu
aed852bf21 cpython-ext: add isatty and close to PyObject wrapping Rust Write
Summary:
Expose the Rust `is_tty` to Python `isatty`. This will unblock switching Python
`fout`, `ferr` to Rust objects.

Reviewed By: sfilipco

Differential Revision: D26612486

fbshipit-source-id: 775c47df461e17f1713943d4b1fe5baeb84beca7
2021-02-23 22:33:48 -08:00
Jun Wu
f3a5686a15 io: add IsTty API
Summary:
Add a new API to test if a stream is a tty. This is needed to replace the
Python `fin`, `fout` etc. to Rust objects, because the Python land requires the
`istty` API. It is also useful for properly implement color detection in the
pure Rust land.

Reviewed By: sfilipco

Differential Revision: D26612480

fbshipit-source-id: 5cf79447b1d74e0031a954788db342afd48dc288
2021-02-23 22:33:47 -08:00
Jun Wu
47d5813a17 cpython-ext: add a general From/ToPyObject for serde types
Summary:
This can be used to automate Python/Rust conversions for complex structures
like `CommitRevlogData`.

Reviewed By: kulshrax

Differential Revision: D23966988

fbshipit-source-id: 17a19d38270e6ef0952c13a1cd778487e84a94ff
2020-10-06 16:01:23 -07:00
Jun Wu
b5a22da53c cpython-ext: add a serde deserializer that converts Python objects to Rust values
Summary:
The goal is to implement `FromPyObject` and `ToPyObject` more easily.
Today crates have to dependent on `cpython` to implement `From/ToPyObject`,
which is somewhat unwanted for pure Rust crates.

The `ser` module used to ignore the `variant` field for non-unit enum variants.
They have been fixed so the serialized value can be deserialized correctly.
For example, `enum E { A, B(T) }` will be serialized to `"A"` for `E::A`, and
`{"B": T}` for `E::B`.

Reviewed By: kulshrax

Differential Revision: D23966994

fbshipit-source-id: c50d57bf313caeec65a604ed9b05a5729f3b3635
2020-10-06 16:01:22 -07:00
Jun Wu
ecbc2abb70 cpython-ext: add a general From/ToPyObject for bytes-like Rust structs
Summary: This can be used by dag::Vertex and minibytes::Bytes.

Reviewed By: kulshrax

Differential Revision: D23966985

fbshipit-source-id: 3b4b29648e038ef49f26ce2b500119e148544d9e
2020-10-02 21:51:49 -07:00
Jun Wu
41b200c8d8 cpython-async: expose Rust Stream to Python
Summary:
The exposed type can be used as a Python iterator:

  for value in stream:
      ...

The Python type can be used as input and output parameters in binding functions:

  # Rust
  type S = TStream<anyhow::Result<X>>;
  def f1() -> PyResult<S> { ... }
  def f2(x: S) -> PyResult<S> { Ok(x.stream().map_ok(...).into()) }

  # Python
  stream1 = f1()
  stream2 = f2(stream1)

This crate is similar to `cpython-ext`: it does not define actual business
logic exposed by `bindings` module. So it's put in `lib`, not
`bindings/modules`.

Reviewed By: markbt

Differential Revision: D23799641

fbshipit-source-id: c13b0c788a6465679b562976728f0002fd872bee
2020-09-21 13:28:07 -07:00
David Tolnay
e83e05ff25 Update formatter to rustfmt 2.0
Reviewed By: zertosh

Differential Revision: D23591028

fbshipit-source-id: f458503fc2b9c25023fa1643eca5e166882a4811
2020-09-09 07:52:34 -07:00
Meyer Jacobs
b9f3c9c692 taggederror: Introduce taggederror-util for more ergonomic error tagging for eden error types.
Summary:
Introduce taggederror-util, which provides a new trait `AnyhowEdenExt`, which provides a method `eden_metadata` for anyhow errors and results. This method works much like `AnyhowExt::common_metadata`, but additionally supports extracting default error metadata from known `Tagged` types which are listed explicitly in the method implementation.

Extend `FilteredAnyhow` to support a configuration "metadata function", which allows swapping out `eden_metadata` for the standard `common_metadata`.

Modify Rust dispatch and Python bindings to use `AnyhowEdenExt` for metadata extraction and printing.

Modify `intentional_error` to rely on `AnyhowEdenExt` for tagging (removes `.tagged` call, no tags will be visible if `AnyhowEdenExt` is not used).

Reviewed By: DurhamG

Differential Revision: D22927203

fbshipit-source-id: 04b36fdfaa24af591118acb9e418d1ed7ae33f91
2020-08-06 19:37:25 -07:00
Jun Wu
78c05bb5e6 cpython-ext: extract io::Error translation to a function
Summary: This will be used later.

Reviewed By: sfilipco

Differential Revision: D22883863

fbshipit-source-id: 4f7ed4eb51d403f96e9d1aa1792062b4c55e3398
2020-08-06 12:31:57 -07:00
Meyer Jacobs
e3b86cf77d debug: introduce binding layer for propagating error metadata to Python
Summary:
Implements based Rust-Python binding layer for error metadata propagation.

We introduce a new type, `TaggedExceptionData`, which carries CommonMetadata and the original (without metadata) error message for a Rust Anyhow error. This class is passed to RustError and can be accessed in Python (somewhat awkwardly) via indexing:
```
except error.RustError as e:
    fault = e.args[0].fault()
    typename = e.args[0].typename()
    message = e.args[0].message()
```
As far as I can tell, due to limitations in cpython-rs, this can't be made more ergonomic without introducing a Python shim around the Rust binding layer, which could adapt the cpython-rs classes to use whatever API we'd like.

Currently, anyhow errors that are not otherwise special-cased will be converted into RustError, with both the original error message and any attached metadata printed as shown below
```
  abort: intentional error for debugging with message 'intentional_error'
  error has type name taggederror::IntentionalError and fault None
```
We can of course re-raise the error if desired to maintain the previous behavior for handling a RustError.

If we'd like other, specialized Rust Python Exception types to carry metadata (such as `IndexedLogError`), we'll need to modify them to accept a `TaggedExceptionData` like `RustError`.

Renamed the "cause an error in pure rust command" function to `debugcauserusterror`, and instead used the name `debugthrowrustexception` for a command which causes an error in rust which is converted to a Python exception across the binding layer.

Introduced a simple integration test which exercises `debugthrowrustexception`.

Added a basic handler for RustError to scmutil.py

Reviewed By: DurhamG

Differential Revision: D22517796

fbshipit-source-id: 0409489243fe739a26958aad48f608890eb93aa0
2020-07-16 19:30:00 -07:00
Arun Kulshreshtha
14a7fe636f cpython-ext: Add ExtractInnerRef trait
Summary: Per comments on D22429347, add a new `ExtractInnerRef` trait that is similar to `ExtractInner`, but returns a reference to the underlying value. A default implementation is provided for types whose inner value is `Clone + 'static`, so in practice most types will only need to implement `ExtractInnerRef`, whereas the callsite may choose whether it needs a reference or an owned value.

Reviewed By: quark-zju

Differential Revision: D22464158

fbshipit-source-id: 7b97329aedcddb0e51fd242b519e79eba2eed350
2020-07-09 19:05:55 -07:00
Arun Kulshreshtha
7ae097e8da cpython-ext: add ExtractInner trait
Summary:
A common pattern in Mercurial's data storage layer Python bindings is to have a Python object that wraps a Rust object. These Python objects are often passed across the FFI boundary to Rust code, which then may need to access the underlying Rust value.

Previously, the objects that used this pattern did so in an ad-hoc manner, typically by providing an `into_inner` or `to_inner` inherent method. This diff introduces a new `ExtractInner` trait that standardizes this pattern into a single interface, which in turn allows this pattern to be used with generics.

Reviewed By: quark-zju

Differential Revision: D22429347

fbshipit-source-id: cab4c24b8b98c6ef8307f72a9b4726aabdc829cc
2020-07-09 19:05:55 -07:00
Carolyn Busch
89f238b8dd Replace whitelist/blacklist term
Summary: Replaces usages of whitelist/blacklist with include/exclude/allow. These terms are more descriptive and less likely to contribute to racial stereotyping. More context: https://fb.workplace.com/groups/sourcecontrolteam/permalink/2926049127516414/

Reviewed By: farnz

Differential Revision: D22039299

fbshipit-source-id: d5b4cdeca681e1f4c992f7ef0b9f772b2ae1abd3
2020-06-15 15:01:19 -07:00
Carolyn Busch
4eeab3b81b Update cpython to 0.5
Summary:
D21270958 updated the cpython, python27-sys, and python3-sys crates to 0.5. Update
the Mercurial cargo dependencies to match.

Reviewed By: xavierd

Differential Revision: D21281875

fbshipit-source-id: ccad68749a25d11240351b5faeef27cb9c693456
2020-04-28 11:47:41 -07:00
Jun Wu
0b5a4ae2c3 cpython-ext: infer errno from io::ErrorKind
Summary:
Sometimes the Rust io::Error is generated without an errno (ex. pipe
0.2 would generate BrokenPipe error without an errno). The Python
land uses errno to check error type (Python does not have io::ErrorKind).

Therefore attempt to translate ErrorKind to Python errno. Without this
exiting the rust pager early would crash like:

  StdioError: [Errno None] pipe reader has been dropped
  abort: pipe reader has been dropped

Reviewed By: markbt

Differential Revision: D20898559

fbshipit-source-id: ef863617e0e500d878ea0f9aeac06b4d87ffbcf2
2020-04-08 13:13:08 -07:00
Xavier Deguillard
767134797c pyerror: stringify Rust errors with "{:?}"
Summary:
According to the anyhow documentation[0], the behavior of `.to_string()` is to
only stringify the top-level errors, hiding all the context of the error.
Instead, the debug format allows all the context to be displayed, and, if
available the backtrace.

This should significantly help debug Rust errors when context is available,
which we should strive to have everywhere!

[0]: https://docs.rs/anyhow/1.0.27/anyhow/struct.Error.html#display-representations

Reviewed By: sfilipco

Differential Revision: D20575944

fbshipit-source-id: 2968d7fb755edec7f7e5151138e8049ded181c1b
2020-03-20 20:22:14 -07:00
Jun Wu
ad8190713b cpython-ext: serialize Rust str into Python str type
Summary:
Previously Rust str was serialized into bytes. To be Python 3 friendly, let's
serialize it into `str`.

Reviewed By: markbt

Differential Revision: D19797706

fbshipit-source-id: 388eb044dc7e25cdc438f0c3d6fa5a5740f22e3d
2020-03-12 12:19:38 -07:00
Jun Wu
7316c4cc22 cpython-ext: add a way to wrap Rust Write object into a Python object
Summary:
The library already has a way to wrap a Python object into a Rust object that
exposes the Rust Read/Write interface. This is the reverse direction for
the Write interface.

The initial intention is to expose Rust stdout as described in D19702533.
However, I found Python's `sys.stdout.buffer` also enforces utf-8 encoding
on Windows (unless PYTHONLEGACYWINDOWSSTDIO is set). So Python's
stdout actually behaves similarly with Rust's stdout on Windows and is okay
to use. That said, it's still useful to have this abstraction, for streampager [1]
integration.

[1]: https://github.com/markbt/streampager/

Reviewed By: sfilipco

Differential Revision: D19716127

fbshipit-source-id: ba39898122561d9a49b7080ee95d7c940540eb40
2020-02-04 18:41:13 -08:00
Mark Thomas
914607cac7 cpython-ext: add PyPath for references to paths
Summary: `PyPath` is to `PyPathBuf` as `Path` is to `PathBuf` and `str` is to `String`.

Reviewed By: quark-zju

Differential Revision: D19647995

fbshipit-source-id: 841a5f6fea295bc72b00da028ae256ca38578504
2020-01-30 17:33:35 -08:00
Mark Thomas
13b7a759a2 cpython-ext: add PyNone, a marker struct for functions that can only return None
Summary: Add `PyNone`.  This is a marker struct that indicates that a python function can only return `PyNone`.

Reviewed By: xavierd

Differential Revision: D19644338

fbshipit-source-id: f846b146237ebf7de996177494934fec662cde0f
2020-01-30 12:28:38 -08:00
Mark Thomas
6b8042662a cpython_ext: rename PyPath to PyPathBuf
Summary:
`PyPath` is the type that owns the data.  Rename it to `PyPathBuf` for analogy
with `PathBuf` and `RepoPathBuf`, and to allow us to introduce a reference type
named `PyPath`.

Reviewed By: xavierd

Differential Revision: D19643797

fbshipit-source-id: 56d80fea5677f7223e967b0723039d1763b26f68
2020-01-30 11:06:24 -08:00
Jun Wu
c5dd6829c7 cpython-ext: add more utilities for PyPath
Summary:
Make the type easier to use. Namely, the treestate bindings want PyPath <->
bytes since treestate internally uses bytes.

Reviewed By: xavierd

Differential Revision: D19635357

fbshipit-source-id: 37d1889b5da1d7f3869bb7820de0219b87b71a8b
2020-01-30 08:27:33 -08:00
Mark Thomas
1e63f205f4 rust-cpython: allow compilation for both py2 and py3
Summary:
Set up the `cpython-ext` and `hgcommands` libraries so that they can compile
against py2 and py3 versions of rust-cpython.  Make py2 the default so
that cargo test still works.

Reviewed By: singhsrb

Differential Revision: D19615656

fbshipit-source-id: 3403e7077deb3c0a9dfe0e3b7d4f4ad1da73bba3
2020-01-28 20:17:20 -08:00
Jun Wu
ed3a2b2247 cpython-ext: add missed types dep
Summary: This is incorrectly removed due to a bad rebase / merge.

Reviewed By: DurhamG

Differential Revision: D19607801

fbshipit-source-id: a6ee7a3f184ff1882eb1f1513f7fed74a7108727
2020-01-28 13:50:14 -08:00
Jun Wu
8703970cea py3: update Cargo.toml to make py3 buildable
Summary:
This makes `make hg3` work. It requires cleaning up the `build` directory when
switching between py2 and py3 build, which will be fixed later.

Reviewed By: DurhamG

Differential Revision: D19604824

fbshipit-source-id: 060ff313420126a5dba935c4451b45dc9af45f13
2020-01-28 13:39:38 -08:00
Xavier Deguillard
d087e39a34 pypathmatcher: use PyPath instead of PyByte
Reviewed By: DurhamG

Differential Revision: D19592136

fbshipit-source-id: 5db6ca629cd920d52ffbf7f10963c44c8f7b203d
2020-01-28 12:40:48 -08:00
Adam Simpkins
beff6fdea7 py3: add additional from() conversion methods for Str
Summary: Add methods to convert to a `Str` object from `String` and from `Vec[u8]`

Reviewed By: xavierd

Differential Revision: D19596743

fbshipit-source-id: 6499f7f1b8329f4d14ce8179a41ed46982a85c8e
2020-01-28 12:25:39 -08:00
Mark Thomas
4fe02f3607 bindings: update to rust-cpython 0.4
Summary: Update to the new version of rust-cpython.  This supports `list.append`, so make use of it.

Reviewed By: xavierd

Differential Revision: D19590905

fbshipit-source-id: 03609d4f698ae8e4380e82b8144caaa205b4c2d4
2020-01-28 10:46:33 -08:00
Stefan Filip
5720b9a2a1 py3/pymanifest: convert path types from PyBytes to PyPath
Reviewed By: xavierd

Differential Revision: D19594134

fbshipit-source-id: e8532a125aa2ed4b7740e669ad572fcbb327692f
2020-01-28 10:29:11 -08:00
Jun Wu
373073df47 py3/rust: cpython-ext: optionally show Python error traceback
Summary:
This is optional, but it helps investigating Python errors chained with other
Rust errors.

For example:

  error.RustError: failed fetching from store (, cc38739855a7f356b4a2aaac0a0a858fd646e6bf)
  Caused by:
    TypeError()
    Traceback (most recent call last):
      File "scm3/edenscm/hgext/remotefilelog/contentstore.py", line 53, in get
        chain = self.getdeltachain(name, node)
      File "scm3/edenscm/hgext/remotefilelog/contentstore.py", line 91, in getdeltachain
        chain = self._getpartialchain(name, node)
      File "scm3/edenscm/hgext/remotefilelog/contentstore.py", line 125, in _getpartialchain
        return store.getdeltachain(name, node)
    TypeError

Without this diff there is only "TypeError()" without the traceback.
This can be turned off by unsetting RUST_BACKTRACE.

Reviewed By: markbt

Differential Revision: D19581173

fbshipit-source-id: 74605b78146b6b1c9ddd5ad720dcd19ff73908a8
2020-01-27 18:56:10 -08:00
Xavier Deguillard
24ae9f9592 cpython-ext: fix python3 compile error
Summary: The format_err is used in shared code too, we need to import it.

Reviewed By: quark-zju

Differential Revision: D19592591

fbshipit-source-id: bd344bf3c295473f4647235a98432d11c9678bf9
2020-01-27 16:58:42 -08:00
Xavier Deguillard
33ea1763ce cpython-ext: add a PyPath type
Summary:
This will be used as an argument to the Rust bindings when using paths. This
type is either a PyBytes in Python2 and uses the various encoding function to
convert into a String, or a PyUnicode in Python3 with no encoding change.

Reviewed By: farnz

Differential Revision: D19587890

fbshipit-source-id: 58903426585693193754691fe3c756b9097b35f6
2020-01-27 16:50:14 -08:00
Xavier Deguillard
e512c370fd py3/rust: cpython-ext: set ob_size on raw PyObject
Summary:
Without this, Rust code using the feature (ex. lz4, used by lz4revlog) will
panic.

Reviewed By: sfilipco

Differential Revision: D19581188

fbshipit-source-id: b499449df4fede27fe66cf8e5af57e8347a0dd48
2020-01-27 16:50:14 -08:00
Xavier Deguillard
f16bb04977 py3/rust: cpython-ext: support memoryview as PySimpleBuf
Summary: Otherwise we got RustPanic when clindex or dagindex reads mmapped changelog.i.

Reviewed By: sfilipco

Differential Revision: D19581189

fbshipit-source-id: 3ee74a1bd000d58272551ae404dcfe7f957bb2c0
2020-01-27 16:50:13 -08:00
Xavier Deguillard
1c697dbc49 py3/rust: cpython-ext: add Str type
Summary: This converts to bytes on Python 2, but unicode on Python 3.

Reviewed By: markbt

Differential Revision: D19581180

fbshipit-source-id: 0de9056a01ae30810a72352387de5a940b37d7ab
2020-01-27 16:50:13 -08:00
Jun Wu
c624847c84 hgtime: limit year in 1900 to 9999
Summary:
The Python `datatime` stdlib has limitations:

- `datetime.datetime` can only express year 1 to 9999.
- `strptime` requires year >= 1900.

Limit the `HgTime` to 1900 ..= 9999 range to be consistent.

Note: Mercurial has an `i32` range limit, which seems to problematic
since `i32::MAX` is Jan 19, 2038. So I kept using `i64`.

This addressed some XXX comments about not returning errors.

The code change is mostly because added error handling.

Reviewed By: sfilipco

Differential Revision: D18946333

fbshipit-source-id: 0e4756457b0f13451dc5008ef19d4670a7aaa7fb
2019-12-22 11:27:32 -08:00
Jun Wu
fbdecc96bb cpython-ext: move foreign error handling to pyerror
Summary:
Make cpython-ext free from business logic. This adds a bit overhead.
But it should be fine given the error cases are considered rare.

Reviewed By: markbt

Differential Revision: D19186692

fbshipit-source-id: daaffc1369a36c781d1badea822bf62a144eb54e
2019-12-22 11:27:29 -08:00
Jun Wu
d4a19306ed cpython-ext: rename fallible to anyhow_result
Summary: We no longer use the `failure` crate. Rename related methods and traits.

Reviewed By: markbt

Differential Revision: D19186694

fbshipit-source-id: 1c83a90ee12db431b7d8e09a9c2cf1d43a4c0f93
2019-12-22 11:27:29 -08:00
Jun Wu
ef3f9b932d cpython-ext: rename mod failure to error
Summary:
We no longer use the `failure` crate. Rename the module.

`cpython-failure` is dropped since it was merged into `cpython-ext`.

Reviewed By: markbt

Differential Revision: D19186693

fbshipit-source-id: 410d1491bcadd8d3272c7e2df08ecbe66fc0fef2
2019-12-22 11:27:29 -08:00