Skip to content

Commit

Permalink
Bind Channel (mamba-org#3001)
Browse files Browse the repository at this point in the history
* Rename binding functions

* Minimal specs bindings

* Add ChannelSpec setters

* Fix flat_set caster

* Bind ChannelSpecs

* Bind Platform

* Rename CondaURL::base > CondaURL::generic

* Automatically convert enums from strings

* Fix CondaURL encoding bug

* Bind CondaURL

* Add comparison for AuthenticationInfo

* Bind AuthenticationInfo

* Rename libmambapy tests

* Bind AuthenticationDataBase

* Fix binding size

* Add weakening_map comparison

* Refactor AuthenticationDataBase bindings

* Bind ChannelResolveParams

* Separate binding utility functions

* Bind CondaURL / subpath

* Fix Channel

* Bind Channel

* Modify specs import

* Remove ChannelSpec setters

* Simplify channel tests
  • Loading branch information
AntoinePrv authored Nov 28, 2023
1 parent abd21cc commit 5509ed3
Show file tree
Hide file tree
Showing 21 changed files with 1,233 additions and 33 deletions.
31 changes: 29 additions & 2 deletions libmamba/include/mamba/specs/authentication_info.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#ifndef MAMBA_SPECS_AUTHENTICATION_INFO_HPP
#define MAMBA_SPECS_AUTHENTICATION_INFO_HPP

#include <functional>
#include <optional>
#include <string>
#include <string_view>
Expand All @@ -17,27 +18,34 @@

namespace mamba::specs
{
class CondaURL;

/** User and password authetification set in the URL. */
struct BasicHTTPAuthentication
{
std::string user;
std::string password;
};

auto operator==(const BasicHTTPAuthentication& a, const BasicHTTPAuthentication& b) -> bool;
auto operator!=(const BasicHTTPAuthentication& a, const BasicHTTPAuthentication& b) -> bool;

/** HTTP Bearer token set in the request headers. */
struct BearerToken
{
std::string token;
};

auto operator==(const BearerToken& a, const BearerToken& b) -> bool;
auto operator!=(const BearerToken& a, const BearerToken& b) -> bool;

/** A Conda token set in the URL path. */
struct CondaToken
{
std::string token;
};

auto operator==(const CondaToken& a, const CondaToken& b) -> bool;
auto operator!=(const CondaToken& a, const CondaToken& b) -> bool;

using AuthenticationInfo = std::variant<BasicHTTPAuthentication, BearerToken, CondaToken>;

/**
Expand Down Expand Up @@ -79,4 +87,23 @@ namespace mamba::specs
using AuthenticationDataBase = util::
weakening_map<std::unordered_map<std::string, AuthenticationInfo>, URLWeakener>;
}

template <>
struct std::hash<mamba::specs::BasicHTTPAuthentication>
{
auto operator()(const mamba::specs::BasicHTTPAuthentication& auth) const -> std::size_t;
};

template <>
struct std::hash<mamba::specs::BearerToken>
{
auto operator()(const mamba::specs::BearerToken& auth) const -> std::size_t;
};

template <>
struct std::hash<mamba::specs::CondaToken>
{
auto operator()(const mamba::specs::CondaToken& auth) const -> std::size_t;
};

#endif
2 changes: 1 addition & 1 deletion libmamba/include/mamba/specs/channel.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ namespace mamba::specs
ChannelResolveParamsView params
) -> channel_list;

Channel(CondaURL url, std::string display_name, util::flat_set<std::string> platforms = {});
Channel(CondaURL url, std::string display_name, platform_list platforms = {});

[[nodiscard]] auto is_package() const -> bool;

Expand Down
2 changes: 1 addition & 1 deletion libmamba/include/mamba/specs/conda_url.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ namespace mamba::specs
explicit CondaURL(util::URL&& url);
explicit CondaURL(const util::URL& url);

auto base() const -> const util::URL&;
[[nodiscard]] auto generic() const -> const util::URL&;

using Base::scheme_is_defaulted;
using Base::scheme;
Expand Down
34 changes: 33 additions & 1 deletion libmamba/include/mamba/util/weakening_map.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,14 @@ namespace mamba::util
template <typename... Args>
explicit weakening_map(weakener_type weakener, Args&&... args);

[[nodiscard]] auto generic() const -> const Base&;

using Base::begin;
using Base::end;
using Base::cbegin;
using Base::cend;

using Base::empty;
using Base::size;
using Base::max_size;

using Base::clear;
Expand All @@ -65,6 +66,8 @@ namespace mamba::util

using Base::at;

[[nodiscard]] auto size() const -> std::size_t;

[[nodiscard]] auto at_weaken(const key_type& key) -> mapped_type&;
[[nodiscard]] auto at_weaken(const key_type& key) const -> const mapped_type&;

Expand All @@ -82,6 +85,11 @@ namespace mamba::util
Weakener m_weakener = {};
};

template <typename M, typename W>
auto operator==(const weakening_map<M, W>& a, const weakening_map<M, W>& b) -> bool;
template <typename M, typename W>
auto operator!=(const weakening_map<M, W>& a, const weakening_map<M, W>& b) -> bool;

/*************************************
* Implementation of weakening_map *
*************************************/
Expand All @@ -100,6 +108,19 @@ namespace mamba::util
{
}

template <typename M, typename W>
auto weakening_map<M, W>::generic() const -> const Base&
{
return *this;
}

template <typename M, typename W>
auto weakening_map<M, W>::size() const -> std::size_t
{
// https://github.com/pybind/pybind11/pull/4952
return Base::size();
}

template <typename M, typename W>
auto weakening_map<M, W>::at_weaken(const key_type& key) -> mapped_type&
{
Expand Down Expand Up @@ -156,5 +177,16 @@ namespace mamba::util
return find_weaken(key) != end();
}

template <typename M, typename W>
auto operator==(const weakening_map<M, W>& a, const weakening_map<M, W>& b) -> bool
{
return a.generic() == b.generic();
}

template <typename M, typename W>
auto operator!=(const weakening_map<M, W>& a, const weakening_map<M, W>& b) -> bool
{
return a.generic() != b.generic();
}
}
#endif
61 changes: 61 additions & 0 deletions libmamba/src/specs/authentication_info.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,48 @@

#include "mamba/specs/authentication_info.hpp"
#include "mamba/util/string.hpp"
#include "mamba/util/tuple_hash.hpp"

namespace mamba::specs
{
namespace
{
auto attrs(const BasicHTTPAuthentication& auth)
{
return std::tie(auth.user, auth.password);
}
}

auto operator==(const BasicHTTPAuthentication& a, const BasicHTTPAuthentication& b) -> bool
{
return attrs(a) == attrs(b);
}

auto operator!=(const BasicHTTPAuthentication& a, const BasicHTTPAuthentication& b) -> bool
{
return !(a == b);
}

auto operator==(const BearerToken& a, const BearerToken& b) -> bool
{
return a.token == b.token;
}

auto operator!=(const BearerToken& a, const BearerToken& b) -> bool
{
return !(a == b);
}

auto operator==(const CondaToken& a, const CondaToken& b) -> bool
{
return a.token == b.token;
}

auto operator!=(const CondaToken& a, const CondaToken& b) -> bool
{
return !(a == b);
}

auto URLWeakener::make_first_key(std::string_view key) const -> std::string
{
if (util::ends_with(key, '/'))
Expand Down Expand Up @@ -38,3 +77,25 @@ namespace mamba::specs
}
}
}

auto
std::hash<mamba::specs::BasicHTTPAuthentication>::operator()(
const mamba::specs::BasicHTTPAuthentication& auth
) const -> std::size_t
{
return mamba::util::hash_tuple(mamba::specs::attrs(auth));
}

auto
std::hash<mamba::specs::BearerToken>::operator()(const mamba::specs::BearerToken& auth) const
-> std::size_t
{
return std::hash<std::string>{}(auth.token);
}

auto
std::hash<mamba::specs::CondaToken>::operator()(const mamba::specs::CondaToken& auth) const
-> std::size_t
{
return std::hash<std::string>{}(auth.token);
}
7 changes: 6 additions & 1 deletion libmamba/src/specs/channel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ namespace mamba::specs
* Implementation of Channel *
*******************************/

Channel::Channel(CondaURL url, std::string display_name, util::flat_set<std::string> platforms)
Channel::Channel(CondaURL url, std::string display_name, platform_list platforms)
: m_url(std::move(url))
, m_display_name(std::move(display_name))
, m_platforms(std::move(platforms))
Expand Down Expand Up @@ -141,6 +141,11 @@ namespace mamba::specs
== util::rstrip(other_url.path_without_token(Decode::no), '/'));
}

auto Channel::is_equivalent_to(const Channel& other) const -> bool
{
return url_equivalent_with(other) && (platforms() == other.platforms());
}

auto Channel::contains_equivalent(const Channel& other) const -> bool
{
return url_equivalent_with(other) && util::set_is_superset_of(platforms(), other.platforms());
Expand Down
8 changes: 4 additions & 4 deletions libmamba/src/specs/conda_url.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ namespace mamba::specs
{
}

auto CondaURL::base() const -> const util::URL&
auto CondaURL::generic() const -> const util::URL&
{
return static_cast<const util::URL&>(*this);
}
Expand Down Expand Up @@ -246,7 +246,7 @@ namespace mamba::specs
auto old_path = clear_path();
old_path.erase(std::min(len, old_path.size()));
Base::set_path(std::move(old_path), Encode::no);
Base::append_path(new_path.empty() ? "/" : new_path);
Base::append_path(new_path.empty() ? "/" : new_path, Encode::no);
}
else
{
Expand Down Expand Up @@ -506,7 +506,7 @@ namespace mamba::specs

auto operator==(const CondaURL& a, const CondaURL& b) -> bool
{
return a.base() == b.base();
return a.generic() == b.generic();
}

auto operator!=(const CondaURL& a, const CondaURL& b) -> bool
Expand All @@ -529,5 +529,5 @@ namespace mamba::specs
auto
std::hash<mamba::specs::CondaURL>::operator()(const mamba::specs::CondaURL& u) const -> std::size_t
{
return std::hash<mamba::util::URL>()(u.base());
return std::hash<mamba::util::URL>()(u.generic());
}
10 changes: 4 additions & 6 deletions libmamba/tests/src/specs/test_channel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,10 @@ TEST_SUITE("specs::channel")
CHECK_EQ(chan_b, chan_a);
CHECK_EQ(chan_a, chan_b);

chan_b = chan_a;
chan_b.set_platforms({ "linux-64", "noarch" });
chan_b = Channel(chan_a.url(), chan_a.display_name(), { "linux-64", "noarch" });
CHECK_NE(chan_b, chan_a);

chan_b = chan_a;
chan_b.set_display_name("othername");
chan_b = Channel(chan_a.url(), "othername", chan_a.platforms());
CHECK_NE(chan_b, chan_a);
}
}
Expand Down Expand Up @@ -111,12 +109,12 @@ TEST_SUITE("specs::channel")
CHECK(chan_a.contains_equivalent(chan_b));
CHECK(chan_b.contains_equivalent(chan_a));

chan_a.set_platforms({ "noarch", "linux-64" });
chan_a = Channel(chan_a.url(), chan_a.display_name(), { "noarch", "linux-64" });
CHECK(chan_a.contains_equivalent(chan_a));
CHECK(chan_a.contains_equivalent(chan_b));
CHECK_FALSE(chan_b.contains_equivalent(chan_a));

chan_b.set_platforms({ "osx-64" });
chan_b = Channel(chan_b.url(), chan_b.display_name(), { "ox-64" });
CHECK_FALSE(chan_a.contains_equivalent(chan_b));
CHECK_FALSE(chan_b.contains_equivalent(chan_a));
}
Expand Down
17 changes: 14 additions & 3 deletions libmamba/tests/src/specs/test_conda_url.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,9 +139,20 @@ TEST_SUITE("specs::CondaURL")
SUBCASE("Encoding")
{
url.set_token("mytoken");
url.set_path_without_token("some / weird/path %");
CHECK_EQ(url.path_without_token(), "/some / weird/path %");
CHECK_EQ(url.path_without_token(CondaURL::Decode::no), "/some%20/%20weird/path%20%25");

SUBCASE("Encode")
{
url.set_path_without_token("some / weird/path %");
CHECK_EQ(url.path_without_token(), "/some / weird/path %");
CHECK_EQ(url.path_without_token(CondaURL::Decode::no), "/some%20/%20weird/path%20%25");
}

SUBCASE("Encoded")
{
url.set_path_without_token("/some%20/%20weird/path%20%25", CondaURL::Encode::no);
CHECK_EQ(url.path_without_token(), "/some / weird/path %");
CHECK_EQ(url.path_without_token(CondaURL::Decode::no), "/some%20/%20weird/path%20%25");
}
}
}

Expand Down
1 change: 1 addition & 0 deletions libmambapy/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ pybind11_add_module(
bindings
src/libmambapy/bindings/longpath.manifest
src/libmambapy/bindings/bindings.cpp
src/libmambapy/bindings/specs.cpp
src/libmambapy/bindings/legacy.cpp
)

Expand Down
2 changes: 2 additions & 0 deletions libmambapy/src/libmambapy/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# Import all submodules so that one can use them directly with `import libmambapy`
import libmambapy.version
import libmambapy.specs

# Legacy which used to combine everything
from libmambapy.bindings.legacy import * # noqa: F403
Expand Down
3 changes: 2 additions & 1 deletion libmambapy/src/libmambapy/bindings/bindings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@

PYBIND11_MODULE(bindings, m)
{
mambapy::legacy::bind_submodule(m.def_submodule("legacy"));
mambapy::bind_submodule_specs(m.def_submodule("specs"));
mambapy::bind_submodule_legacy(m.def_submodule("legacy"));
}
10 changes: 4 additions & 6 deletions libmambapy/src/libmambapy/bindings/bindings.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,14 @@
//
// The full license is in the file LICENSE, distributed with this software.

#ifndef LIBMAMBAPY_HPP
#define LIBMAMBAPY_HPP
#ifndef LIBMAMBAPY_BINDINGS_HPP
#define LIBMAMBAPY_BINDINGS_HPP

#include <pybind11/pybind11.h>

namespace mambapy
{
namespace legacy
{
void bind_submodule(pybind11::module_ m);
}
void bind_submodule_specs(pybind11::module_ m);
void bind_submodule_legacy(pybind11::module_ m);
}
#endif
2 changes: 1 addition & 1 deletion libmambapy/src/libmambapy/bindings/flat_set_caster.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ namespace PYBIND11_NAMESPACE
{
template <typename Key, typename Compare, typename Alloc>
struct type_caster<mamba::util::flat_set<Key, Compare, Alloc>>
: set_caster<std::set<Key, Compare, Alloc>, Key>
: set_caster<mamba::util::flat_set<Key, Compare, Alloc>, Key>
{
};
}
Expand Down
Loading

0 comments on commit 5509ed3

Please sign in to comment.