Comparison 2 fields of model between himself

Checks

[ ]1 I added a descriptive title to this issue
[ 1] I have searched (google, github) for similar issues and couldn't find anything
[1 ] I have read and followed the docs and couldn't find an answer
[ ] After submitting this, I commit to one of:

Look through open issues and helped at least one other person

Question
I have 2 models:
class UserProfileData(BaseModel):
    smoking: Optional[int] = Field(..., ge=0, le=4, description="How mach user = smoking", example=2)
    alcohol: Optional[int] = Field(..., ge=0, le=4, description="How mach user = alcohol", example=2)
    height: Optional[int] = Field(..., ge=50, le=250, description="Height of the user", example=180)
    weight: Optional[int] = Field(..., ge=20, le=200, description="weight of the user", example=80)

class UserSearchPreferences(BaseModel):  # UserProfileData is low boundary
    smoking_high_boudary: Optional[int] = Field(..., ge=0, le=4, description="How mach user = smoking", example=2)
    alcohol_high_boudary: Optional[int] = Field(..., ge=0, le=4, description="How mach user = alcohol", example=2)
    height_high_boudary: Optional[int] = Field(..., ge=50, le=250, description="Height of the user", example=180)
    weight_high_boudary: Optional[int] = Field(..., ge=20, le=200, description="weight of the user", example=80)

I want to check that every filed of something_high_boudary > something, i.e. weight_high_boudary > weight.
Ho I can do it?

Hi @david-shiko
You'll need to bind your two models one way or another and then use validator on the second field or root_validator.
For example
from typing import Dict, Optional

from pydantic import BaseModel, validator

class UserProfileData(BaseModel):
    smoking: Optional[int]
    alcohol: Optional[int]

class UserSearchPreferences(BaseModel):
    smoking_high_boundary: Optional[int]
    alcohol_high_boundary: Optional[int]

class Checker(BaseModel):
    data: UserProfileData
    prefs: UserSearchPreferences

    @validator('prefs')
    def ensure_bigger(cls, u_prefs: UserSearchPreferences, values: dict) -> UserSearchPreferences:
        u_data: UserProfileData = values['data']
        for field, value in u_data:
            high_boundary = getattr(u_prefs, f'{field}_high_boundary', None)
            if value is not None and high_boundary is not None and high_boundary < value:
                raise ValueError(
                    f'Value for {field!r} is too high! '
                    f'(value: {value}, high boundary: {high_boundary})'
                )
        return u_prefs

Checker(
    data=UserProfileData(smoking=1, alcohol=2),
    prefs=UserSearchPreferences(smoking_high_boundary=3, alcohol_high_boundary=5)
)
# OK
try:
    Checker(
        data=UserProfileData(smoking=4, alcohol=2),
        prefs=UserSearchPreferences(smoking_high_boundary=3, alcohol_high_boundary=5)
    )
except ValueError as e:
    print(e)
    # 1 validation error for Checker
    # prefs
    #   Value for 'smoking' is too high! (value: 4, high boundary: 3) (type=value_error)

Hope it helps!

Hi @david-shiko
You'll need to bind your two models one way or another and then use validator on the second field or root_validator.
For example
from typing import Dict, Optional

from pydantic import BaseModel, validator

class UserProfileData(BaseModel):
    smoking: Optional[int]
    alcohol: Optional[int]

class UserSearchPreferences(BaseModel):
    smoking_high_boundary: Optional[int]
    alcohol_high_boundary: Optional[int]

class Checker(BaseModel):
    data: UserProfileData
    prefs: UserSearchPreferences

    @validator('prefs')
    def ensure_bigger(cls, u_prefs: UserSearchPreferences, values: dict) -> UserSearchPreferences:
        u_data: UserProfileData = values['data']
        for field, value in u_data:
            high_boundary = getattr(u_prefs, f'{field}_high_boundary', None)
            if value is not None and high_boundary is not None and high_boundary < value:
                raise ValueError(
                    f'Value for {field!r} is too high! '
                    f'(value: {value}, high boundary: {high_boundary})'
                )
        return u_prefs

Checker(
    data=UserProfileData(smoking=1, alcohol=2),
    prefs=UserSearchPreferences(smoking_high_boundary=3, alcohol_high_boundary=5)
)
# OK
try:
    Checker(
        data=UserProfileData(smoking=4, alcohol=2),
        prefs=UserSearchPreferences(smoking_high_boundary=3, alcohol_high_boundary=5)
    )
except ValueError as e:
    print(e)
    # 1 validation error for Checker
    # prefs
    #   Value for 'smoking' is too high! (value: 4, high boundary: 3) (type=value_error)

Hope it helps!

hi @PrettyWood!
Thank you a lot for a help!
I'm verry sorry, but I asked an incrorrect question, because indeed UserSearchPreferences inherits from UserProfileData (just because it has the same fileds). It's probably must make change a solution.

hi @PrettyWood!
Thank you a lot for a help!
I'm verry sorry, but I asked an incrorrect question, because indeed UserSearchPreferences inherits from UserProfileData (just because it has the same fileds). It's probably must make change a solution.

Hi @david-shiko
The easiest would probably be
from typing import Any, Dict, Optional

from pydantic import BaseModel, root_validator

class UserProfileData(BaseModel):
    smoking: Optional[int]
    alcohol: Optional[int]

class UserSearchPreferences(UserProfileData):
    smoking_high_boundary: Optional[int]
    alcohol_high_boundary: Optional[int]

    @root_validator
    def ensure_bigger(cls, values: Dict[str, Any]) -> Dict[str, Any]:
        for field in UserProfileData.__fields__:
            value = values.get(field)
            high_boundary = values.get(f'{field}_high_boundary')
            if value is not None and high_boundary is not None and high_boundary < value:
                raise ValueError(
                    f'Value for {field!r} is too high! '
                    f'(value: {value}, high boundary: {high_boundary})'
                )
        return values

UserSearchPreferences(smoking=1, alcohol=2, smoking_high_boundary=3, alcohol_high_boundary=5)
# OK
try:
    UserSearchPreferences(smoking=4, alcohol=2, smoking_high_boundary=3, alcohol_high_boundary=5)
except ValueError as e:
    print(e)
    # 1 validation error for Checker
    # prefs
    #   Value for 'smoking' is too high! (value: 4, high boundary: 3) (type=value_error)

Hi @david-shiko
The easiest would probably be
from typing import Any, Dict, Optional

from pydantic import BaseModel, root_validator

class UserProfileData(BaseModel):
    smoking: Optional[int]
    alcohol: Optional[int]

class UserSearchPreferences(UserProfileData):
    smoking_high_boundary: Optional[int]
    alcohol_high_boundary: Optional[int]

    @root_validator
    def ensure_bigger(cls, values: Dict[str, Any]) -> Dict[str, Any]:
        for field in UserProfileData.__fields__:
            value = values.get(field)
            high_boundary = values.get(f'{field}_high_boundary')
            if value is not None and high_boundary is not None and high_boundary < value:
                raise ValueError(
                    f'Value for {field!r} is too high! '
                    f'(value: {value}, high boundary: {high_boundary})'
                )
        return values

UserSearchPreferences(smoking=1, alcohol=2, smoking_high_boundary=3, alcohol_high_boundary=5)
# OK
try:
    UserSearchPreferences(smoking=4, alcohol=2, smoking_high_boundary=3, alcohol_high_boundary=5)
except ValueError as e:
    print(e)
    # 1 validation error for Checker
    # prefs
    #   Value for 'smoking' is too high! (value: 4, high boundary: 3) (type=value_error)

@PrettyWood!
It's funny, but I can't find out how to extract current incoming values from a such structure ?
class UserSearchPreferences(BaseModel):
    smoking: Optional[dict] = {
        'low_boundary': Field(..., ge=0, le=4, description="Minimal boundary smoking", example=2),
        'high_boundary': Field(..., ge=0, le=4, description="Maximum boundary smoking", example=2)}
    alcohol: Optional[dict] = {
        'low_boundary': Field(..., ge=0, le=4, description="Minimal boundary smoking", example=2),
        'high_boundary': Field(..., ge=0, le=4, description="Maximum boundary smoking", example=2)}

P.S. I decaded to choose an another way to make it more convient.

@PrettyWood!
It's funny, but I can't find out how to extract current incoming values from a such structure ?
class UserSearchPreferences(BaseModel):
    smoking: Optional[dict] = {
        'low_boundary': Field(..., ge=0, le=4, description="Minimal boundary smoking", example=2),
        'high_boundary': Field(..., ge=0, le=4, description="Maximum boundary smoking", example=2)}
    alcohol: Optional[dict] = {
        'low_boundary': Field(..., ge=0, le=4, description="Minimal boundary smoking", example=2),
        'high_boundary': Field(..., ge=0, le=4, description="Maximum boundary smoking", example=2)}

P.S. I decaded to choose an another way to make it more convient.

@PrettyWood
Thank u for a help, by your suggestion I maked another solution (because eventually I fugure out that UserSearchPreferences can't inherit form UserProfile cuz other reasosns).
My solution:
class UserSwipes(BaseModel):  # Consider UserProfile attributes as low boundary
    smoking_low: Optional[int] = Field(..., ge=0, le=4, description="Minimal boundary smoking", example=2)
    smoking_high: Optional[int] = Field(..., ge=0, le=4, description="Maximum boundary smoking", example=3)
    alcohol_low: Optional[int] = Field(..., ge=0, le=4, description="Minimal boundary smoking", example=2)
    alcohol_high: Optional[int] = Field(..., ge=0, le=4, description="Maximum boundary smoking", example=3)
    kids_low: Optional[int] = Field(..., ge=0, le=4, description="Minimal boundary smoking", example=2)
    kids_high: Optional[int] = Field(..., ge=0, le=4, description="Maximum boundary smoking", example=3)
    height_low: Optional[int] = Field(..., ge=0, le=4, description="Minimal boundary smoking", example=2)
    height_high: Optional[int] = Field(..., ge=0, le=4, description="Maximum boundary smoking", example=3)
    weight_low: Optional[int] = Field(..., ge=0, le=4, description="Minimal boundary smoking", example=2)
    weight_high: Optional[int] = Field(..., ge=0, le=4, description="Maximum boundary smoking", example=3)
    sport_low: Optional[int] = Field(..., ge=0, le=4, description="Minimal boundary smoking", example=2)
    sport_high: Optional[int] = Field(..., ge=0, le=4, description="Maximum boundary smoking", example=3)

    @root_validator
    def ensure_bigger(cls, values: dict[str]) -> dict[str]:
        old_k_v = next(iter(values.items()))  # Get tuple first pair of key-value
        for k, v in values.items():
            if 'low' in k:
                old_k_v = k, v
            else:
                if k.split('_')[0] == old_k_v[0].split('_')[0]:
                    if old_k_v[-1] > v:
                        raise Exception('Minimal value biggest that Maximum item!')
                else:
                    raise Exception("'high' item must follow 'low' item.")
        return values

I tryied to link low and high somehow (dict or list, but failed, as I understood, pydantic can't combine Field-s.
P.S. I also come accross with another question (stackoverflow)

@PrettyWood
Thank u for a help, by your suggestion I maked another solution (because eventually I fugure out that UserSearchPreferences can't inherit form UserProfile cuz other reasosns).
My solution:
class UserSwipes(BaseModel):  # Consider UserProfile attributes as low boundary
    smoking_low: Optional[int] = Field(..., ge=0, le=4, description="Minimal boundary smoking", example=2)
    smoking_high: Optional[int] = Field(..., ge=0, le=4, description="Maximum boundary smoking", example=3)
    alcohol_low: Optional[int] = Field(..., ge=0, le=4, description="Minimal boundary smoking", example=2)
    alcohol_high: Optional[int] = Field(..., ge=0, le=4, description="Maximum boundary smoking", example=3)
    kids_low: Optional[int] = Field(..., ge=0, le=4, description="Minimal boundary smoking", example=2)
    kids_high: Optional[int] = Field(..., ge=0, le=4, description="Maximum boundary smoking", example=3)
    height_low: Optional[int] = Field(..., ge=0, le=4, description="Minimal boundary smoking", example=2)
    height_high: Optional[int] = Field(..., ge=0, le=4, description="Maximum boundary smoking", example=3)
    weight_low: Optional[int] = Field(..., ge=0, le=4, description="Minimal boundary smoking", example=2)
    weight_high: Optional[int] = Field(..., ge=0, le=4, description="Maximum boundary smoking", example=3)
    sport_low: Optional[int] = Field(..., ge=0, le=4, description="Minimal boundary smoking", example=2)
    sport_high: Optional[int] = Field(..., ge=0, le=4, description="Maximum boundary smoking", example=3)

    @root_validator
    def ensure_bigger(cls, values: dict[str]) -> dict[str]:
        old_k_v = next(iter(values.items()))  # Get tuple first pair of key-value
        for k, v in values.items():
            if 'low' in k:
                old_k_v = k, v
            else:
                if k.split('_')[0] == old_k_v[0].split('_')[0]:
                    if old_k_v[-1] > v:
                        raise Exception('Minimal value biggest that Maximum item!')
                else:
                    raise Exception("'high' item must follow 'low' item.")
        return values

I tryied to link low and high somehow (dict or list, but failed, as I understood, pydantic can't combine Field-s.
P.S. I also come accross with another question (stackoverflow)

Here is a little helper
from typing import Optional, Type, TypeVar

from pydantic import BaseModel, create_model

BaseModelT = TypeVar('BaseModelT', bound=BaseModel)

def to_optional(model: Type[BaseModelT], name: Optional[str] = None) -> Type[BaseModelT]:
    """
    Create a new BaseModel with the exact same fields as `model`
    but making them all optional
    """
    field_definitions = {
        name: (field.outer_type_, None)
        for name, field in model.__fields__.items()
    }
    return create_model(name or f'Optional{model.__name__}', **field_definitions)  # type: ignore[arg-type]

class Model(BaseModel):
    a: str
    b: int

print(Model.__fields__)
# {'a': ModelField(name='a', type=str, required=True), 'b': ModelField(name='b', type=int, required=True)}
print(to_optional(Model).__fields__)
# {'a': ModelField(name='a', type=Optional[str], required=False, default=None), 'b': ModelField(name='b', type=Optional[int], required=False, default=None)}

class Test(to_optional(Model)):
    x: bool

print(Test.__fields__)
# {'a': ModelField(name='a', type=Optional[str], required=False, default=None), 'b': ModelField(name='b', type=Optional[int], required=False, default=None), 'x': ModelField(name='x', type=bool, required=True)}

Hope it helps ;)

Here is a little helper
from typing import Optional, Type, TypeVar

from pydantic import BaseModel, create_model

BaseModelT = TypeVar('BaseModelT', bound=BaseModel)

def to_optional(model: Type[BaseModelT], name: Optional[str] = None) -> Type[BaseModelT]:
    """
    Create a new BaseModel with the exact same fields as `model`
    but making them all optional
    """
    field_definitions = {
        name: (field.outer_type_, None)
        for name, field in model.__fields__.items()
    }
    return create_model(name or f'Optional{model.__name__}', **field_definitions)  # type: ignore[arg-type]

class Model(BaseModel):
    a: str
    b: int

print(Model.__fields__)
# {'a': ModelField(name='a', type=str, required=True), 'b': ModelField(name='b', type=int, required=True)}
print(to_optional(Model).__fields__)
# {'a': ModelField(name='a', type=Optional[str], required=False, default=None), 'b': ModelField(name='b', type=Optional[int], required=False, default=None)}

class Test(to_optional(Model)):
    x: bool

print(Test.__fields__)
# {'a': ModelField(name='a', type=Optional[str], required=False, default=None), 'b': ModelField(name='b', type=Optional[int], required=False, default=None), 'x': ModelField(name='x', type=bool, required=True)}

Hope it helps ;)

Fine! I added an answer to the portal. Can I share a cup of coffee with you?

Fine! I added an answer to the portal. Can I share a cup of coffee with you?

@PrettyWood Unfortunately this solution isn't working correctly with FastAPI. it's missing field info (example, description, i.e. like
Field(
        ..., max_length=16,
        description="One of the media types",
        example='photo')

@PrettyWood Unfortunately this solution isn't working correctly with FastAPI. it's missing field info (example, description, i.e. like
Field(
        ..., max_length=16,
        description="One of the media types",
        example='photo')

Ah yes sorry my bad my solution didn't support complex fields (with Field(........) syntax)
How about that?
from copy import deepcopy
from pprint import pprint
from typing import Optional, Type, TypeVar

from pydantic import BaseModel, Field, create_model

BaseModelT = TypeVar('BaseModelT', bound=BaseModel)

def to_optional(model: Type[BaseModelT], name: Optional[str] = None) -> Type[BaseModelT]:
    """
    Create a new BaseModel with the exact same fields as `model`
    but making them all optional
    """
    field_definitions = {}
    for name, field in model.__fields__.items():
        optional_field_info = deepcopy(field.field_info)
        # Do not change default value of fields that are already optional
        if optional_field_info.default is ...:
            optional_field_info.default = None
        field_definitions[name] = (field.outer_type_, optional_field_info)

    return create_model(name or f'Optional{model.__name__}', **field_definitions)  # type: ignore[arg-type]

class Model(BaseModel):
    a: str
    b: str = 'default_b'
    c: str = Field(..., alias='alias_c')
    d: str = Field('default_d', alias='alias_d')

pprint(Model.__fields__)
# {
#   'a': ModelField(name='a', type=str, required=True),
#   'b': ModelField(name='b', type=str, required=False, default='default_b'),
#   'c': ModelField(name='c', type=str, required=True, alias='alias_c'),
#   'd': ModelField(name='d', type=str, required=False, default='default_d', alias='alias_d')
# }
pprint(to_optional(Model).__fields__)
# {
#   'a': ModelField(name='a', type=Optional[str], required=False, default=None),
#   'b': ModelField(name='b', type=str, required=False, default='default_b'),
#   'c': ModelField(name='c', type=Optional[str], required=False, default=None, alias='alias_c'),
#   'd': ModelField(name='d', type=str, required=False, default='default_d', alias='alias_d')
# }

Ah yes sorry my bad my solution didn't support complex fields (with Field(........) syntax)
How about that?
from copy import deepcopy
from pprint import pprint
from typing import Optional, Type, TypeVar

from pydantic import BaseModel, Field, create_model

BaseModelT = TypeVar('BaseModelT', bound=BaseModel)

def to_optional(model: Type[BaseModelT], name: Optional[str] = None) -> Type[BaseModelT]:
    """
    Create a new BaseModel with the exact same fields as `model`
    but making them all optional
    """
    field_definitions = {}
    for name, field in model.__fields__.items():
        optional_field_info = deepcopy(field.field_info)
        # Do not change default value of fields that are already optional
        if optional_field_info.default is ...:
            optional_field_info.default = None
        field_definitions[name] = (field.outer_type_, optional_field_info)

    return create_model(name or f'Optional{model.__name__}', **field_definitions)  # type: ignore[arg-type]

class Model(BaseModel):
    a: str
    b: str = 'default_b'
    c: str = Field(..., alias='alias_c')
    d: str = Field('default_d', alias='alias_d')

pprint(Model.__fields__)
# {
#   'a': ModelField(name='a', type=str, required=True),
#   'b': ModelField(name='b', type=str, required=False, default='default_b'),
#   'c': ModelField(name='c', type=str, required=True, alias='alias_c'),
#   'd': ModelField(name='d', type=str, required=False, default='default_d', alias='alias_d')
# }
pprint(to_optional(Model).__fields__)
# {
#   'a': ModelField(name='a', type=Optional[str], required=False, default=None),
#   'b': ModelField(name='b', type=str, required=False, default='default_b'),
#   'c': ModelField(name='c', type=Optional[str], required=False, default=None, alias='alias_c'),
#   'd': ModelField(name='d', type=str, required=False, default='default_d', alias='alias_d')
# }

Ah yes sorry my bad my solution didn't support complex fields (with Field(........) syntax)
How about that?
from copy import deepcopy
from pprint import pprint
from typing import Optional, Type, TypeVar

from pydantic import BaseModel, Field, create_model

BaseModelT = TypeVar('BaseModelT', bound=BaseModel)

def to_optional(model: Type[BaseModelT], name: Optional[str] = None) -> Type[BaseModelT]:
    """
    Create a new BaseModel with the exact same fields as `model`
    but making them all optional
    """
    field_definitions = {}
    for name, field in model.__fields__.items():
        optional_field_info = deepcopy(field.field_info)
        # Do not change default value of fields that are already optional
        if optional_field_info.default is ...:
            optional_field_info.default = None
        field_definitions[name] = (field.outer_type_, optional_field_info)

    return create_model(name or f'Optional{model.__name__}', **field_definitions)  # type: ignore[arg-type]

class Model(BaseModel):
    a: str
    b: str = 'default_b'
    c: str = Field(..., alias='alias_c')
    d: str = Field('default_d', alias='alias_d')

pprint(Model.__fields__)
# {
#   'a': ModelField(name='a', type=str, required=True),
#   'b': ModelField(name='b', type=str, required=False, default='default_b'),
#   'c': ModelField(name='c', type=str, required=True, alias='alias_c'),
#   'd': ModelField(name='d', type=str, required=False, default='default_d', alias='alias_d')
# }
pprint(to_optional(Model).__fields__)
# {
#   'a': ModelField(name='a', type=Optional[str], required=False, default=None),
#   'b': ModelField(name='b', type=str, required=False, default='default_b'),
#   'c': ModelField(name='c', type=Optional[str], required=False, default=None, alias='alias_c'),
#   'd': ModelField(name='d', type=str, required=False, default='default_d', alias='alias_d')
# }

@PrettyWood Unfortunately this solution isn't working because of another subtle error:
ValueError: On field "category" the following field constraints are set but not enforced: max_length.

Ah yes sorry my bad my solution didn't support complex fields (with Field(........) syntax)
How about that?
from copy import deepcopy
from pprint import pprint
from typing import Optional, Type, TypeVar

from pydantic import BaseModel, Field, create_model

BaseModelT = TypeVar('BaseModelT', bound=BaseModel)

def to_optional(model: Type[BaseModelT], name: Optional[str] = None) -> Type[BaseModelT]:
    """
    Create a new BaseModel with the exact same fields as `model`
    but making them all optional
    """
    field_definitions = {}
    for name, field in model.__fields__.items():
        optional_field_info = deepcopy(field.field_info)
        # Do not change default value of fields that are already optional
        if optional_field_info.default is ...:
            optional_field_info.default = None
        field_definitions[name] = (field.outer_type_, optional_field_info)

    return create_model(name or f'Optional{model.__name__}', **field_definitions)  # type: ignore[arg-type]

class Model(BaseModel):
    a: str
    b: str = 'default_b'
    c: str = Field(..., alias='alias_c')
    d: str = Field('default_d', alias='alias_d')

pprint(Model.__fields__)
# {
#   'a': ModelField(name='a', type=str, required=True),
#   'b': ModelField(name='b', type=str, required=False, default='default_b'),
#   'c': ModelField(name='c', type=str, required=True, alias='alias_c'),
#   'd': ModelField(name='d', type=str, required=False, default='default_d', alias='alias_d')
# }
pprint(to_optional(Model).__fields__)
# {
#   'a': ModelField(name='a', type=Optional[str], required=False, default=None),
#   'b': ModelField(name='b', type=str, required=False, default='default_b'),
#   'c': ModelField(name='c', type=Optional[str], required=False, default=None, alias='alias_c'),
#   'd': ModelField(name='d', type=str, required=False, default='default_d', alias='alias_d')
# }

@PrettyWood Unfortunately this solution isn't working because of another subtle error:
ValueError: On field "category" the following field constraints are set but not enforced: max_length.

Ah yes this is tricky as the type is already resolved. You could handle this special case by checking in the __mro__ but probably easier to first try this solution, which just checks for the initial type in the __annotations__
from copy import deepcopy
from typing import Optional, Type, TypeVar

from pydantic import BaseModel, create_model

BaseModelT = TypeVar('BaseModelT', bound=BaseModel)

def to_optional(model: Type[BaseModelT], name: Optional[str] = None) -> Type[BaseModelT]:
    """
    Create a new BaseModel with the exact same fields as `model`
    but making them all optional
    """
    field_definitions = {}

    for name, field in model.__fields__.items():
        optional_field_info = deepcopy(field.field_info)
        # Do not change default value of fields that are already optional
        if optional_field_info.default is ...:
            optional_field_info.default = None

        field_type = model.__annotations__.get(name) or field.outer_type_
        field_definitions[name] = (field_type, optional_field_info)

    return create_model(name or f'Optional{model.__name__}', **field_definitions)  # type: ignore[arg-type]

Ah yes this is tricky as the type is already resolved. You could handle this special case by checking in the __mro__ but probably easier to first try this solution, which just checks for the initial type in the __annotations__
from copy import deepcopy
from typing import Optional, Type, TypeVar

from pydantic import BaseModel, create_model

BaseModelT = TypeVar('BaseModelT', bound=BaseModel)

def to_optional(model: Type[BaseModelT], name: Optional[str] = None) -> Type[BaseModelT]:
    """
    Create a new BaseModel with the exact same fields as `model`
    but making them all optional
    """
    field_definitions = {}

    for name, field in model.__fields__.items():
        optional_field_info = deepcopy(field.field_info)
        # Do not change default value of fields that are already optional
        if optional_field_info.default is ...:
            optional_field_info.default = None

        field_type = model.__annotations__.get(name) or field.outer_type_
        field_definitions[name] = (field_type, optional_field_info)

    return create_model(name or f'Optional{model.__name__}', **field_definitions)  # type: ignore[arg-type]

For some reason, I can't inherit from schemas with to_optional.
class UserLogIn(BaseModel):
    email: EmailStr = Field(default=..., description="email"<EMAIL_ADDRESS>    password: str = Field(default=..., min_length=8, max_length=64, description="pass", example='blah blah')

    @validator('password')
    def password_hashing(cls, v):
        return pwd_context.hash(v)

class UserCreate(UserLogIn):  # FEATURE add location
    avatar: HttpUrl = Field(default=..., description="Avatar", example="https://picsum.photos/200")
    first_name: str = Field(default=..., max_length=20, description="First name, a single word", example='Ivan')
    gender: int = Field(default=..., ge=1, le=2, description="1 is male, 2 is female", example=1)
    birthdate: date = Field(default=..., description="Age, two digits", example='1980-1-1')
    comment: Optional[str] = Field(default=None, max_length=512, description="lorem ipsum ", example='blah blah')

    @validator('birthdate')
    def date_validation(cls, v):
        if not date(year=1950, month=1, day=1) < v < date(year=2011, month=1, day=1):
            raise ValueError(f'birthdate must be in range '
                             f'{date(year=1950, month=1, day=1)} - {date(year=2011, month=1, day=1)}')

    class Config:
        orm_mode = True

class UserUpdate(to_optional(UserCreate)):

    class Config:
        orm_mode = True

Traceback (most recent call last):
  File "<frozen importlib._bootstrap>", line 1058, in _handle_fromlist
  File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed
  File "/home/david/PycharmProjects/rubik_love_api/app/schemas.py", line 205, in <module>
    class UserUpdate(to_optional(UserCreate), UserIcons):
  File "/home/david/PycharmProjects/rubik_love_api/app/schemas.py", line 113, in to_optional
    return create_model(name or f'Optional{model.__name__}', **field_definitions)
  File "pydantic/main.py", line 930, in pydantic.main.create_model
  File "pydantic/main.py", line 262, in pydantic.main.ModelMetaclass.__new__
  File "pydantic/fields.py", line 314, in pydantic.fields.ModelField.infer
  File "pydantic/schema.py", line 951, in pydantic.schema.get_annotation_from_field_info
ValueError: On field "password" the following field constraints are set but not enforced: min_length, max_length.
For more details see https://pydantic-docs.helpmanual.io/usage/schema/#unenforced-field-constraints

Here is a patched version
def to_optional(model: Type[BaseModelT], name: Optional[str] = None) -> Type[BaseModelT]:
    """
    Create a new BaseModel with the exact same fields as `model`
    but making them all optional
    """
    all_annotations = {}
    # Workaround to retrieve the passed type and not the resolved one
    # (e.g. `str` with constraints that resolved in `ConstrainedStrValue`)
    for base in reversed(model.__bases__):
        all_annotations.update(getattr(base, '__annotations__', {}))
    all_annotations.update(model.__annotations__)

    field_definitions = {}

    for name, field in model.__fields__.items():
        optional_field_info = deepcopy(field.field_info)
        # Do not change default value of fields that are already optional
        if optional_field_info.default is ...:
            optional_field_info.default = None

        field_type = all_annotations.get(name, field.outer_type_)
        field_definitions[name] = (field_type, optional_field_info)

    return create_model(name or f'Optional{model.__name__}', **field_definitions)  # type: ignore[arg-type]

Howdy there after a long quiet! :)
I applied a code from this comment. It's working well, but how I can validate the field if it exists?
Example:
class PhoneNumber(BaseModel):
    phone_number: str = Field(default=..., min_length=8, max_length=20, description="Номер телефона", example='+79319643333')  # TODO make me with spaces
    class Config:
        orm_mode = True

    @validator('phone_number')
    def valid_phone(cls, v: str):
        phone_number_obj = phonenumbers.parse(number=v)  # Raise error if not seems like a phone number
        phone_number = f"+7{''.join([i for i in v if i.isdecimal()])[1:]}"
        if not phonenumbers.is_valid_number(phone_number_obj) or len(phone_number) < 10:  # TODO test it
            raise ValueError('Incorrect phone number')
        return phone_number

class UserLogIn(PhoneNumber):
    full_name: str = Field(default=..., description="ФИО", example='Чехов Антон Павлович')
    class Config:
        orm_mode = True

class UserUpdate(to_optional(model=UserLogIn, name='UserUpdate')):
    class Config:
        orm_mode = True

new_user = UserUpdate(**{'phone_number': '+7 931 964 foo'})  # No throw error :(

@david-shiko I updated the code above :) Just forgot the __base__ to inherit all the fields. I also fixed the name of the class which was overwritten by the for loop. Hope it helps!

Suddenly I got an error for this schemes:
Parent scema:
class ClinicCreate(FullName):
    clinic_full_name: str = Field(
        default=...,
        max_length=128,
        description="Полное название организации/мед. учреждения.",
        example='Общая бесплатная непрофильная городская больница №52 Имени Амосова Николай Михайловича')

    clinic_short_name: str = Field(
        default=...,
        max_length=64,
        description="Сокращенное название организации/мед. учреждения.",
        example='Городская больница №52.')

    clinic_phone_number: PhoneNumber

    manager_phone_number: PhoneNumber

    manager_login: str = Field(
        default=...,
        min_length=4,
        max_length=32,
        description="Логин руководителя",
        example='Cool Manager')

    password: Password

    @root_validator()
    def rename_fields_for_db(cls, values):
        values['manager_full_name'] = values['full_name']
        values['full_name'] = values['clinic_full_name']
        values['short_name'] = values['clinic_short_name']
        del values['clinic_full_name']
        del values['clinic_short_name']
        # No mess and delete "full_name". Incoming full_name is manager_full_name, output full_name is clinic_full_name
        return values

Child schema:
class ClinicUpdate(to_optional(model=ClinicCreate, model_name='ClinicUpdate')):
    pass

Error:
    for field_name, field in model.__fields__.items():
AttributeError: type object 'ClinicCreate' has no attribute '__fields__'

what is your FullName?

class FullName(str):
    min_length = 4
    max_length = 64

    @classmethod
    def validate_full_name(cls, v: str):
        for letter in v:
            if not letter.isascii():
                raise ValueError('Only ascii symbols allowed (mainly english letter, common symbols and digests)!')
        if len(v.split()) < 2:
            raise ValueError('Incorrect full name')
        return v

    @classmethod
    def __modify_schema__(cls, field_schema):
        field_schema.update(description="ФИО (логин) пользователя",
                            example='Чехов Антон Павлович')

    @classmethod
    def __get_validators__(cls):
        yield cls.validate_full_name
        yield validators.constr_length_validator

ClinicCreate is not a BaseModel then so it has no __fields__ indeed

Ohh, Thank you! I forgot to change parent after refactoring, sorry for the inconvenience.

Here is a patched version
from copy import deepcopy
from typing import Optional, Type, TypeVar

from pydantic import BaseModel, create_model

BaseModelT = TypeVar('BaseModelT', bound=BaseModel)

def to_optional(model: Type[BaseModelT], model_name: Optional[str] = None) -> Type[BaseModelT]:
    """
    Create a new BaseModel with the exact same fields as `model`
    but making them all optional
    """
    all_annotations = {}
    # Workaround to retrieve the passed type and not the resolved one
    # (e.g. `str` with constraints that resolved in `ConstrainedStrValue`)
    for base in reversed(model.__bases__):
        all_annotations.update(getattr(base, '__annotations__', {}))
    all_annotations.update(model.__annotations__)

    field_definitions = {}

    for field_name, field in model.__fields__.items():
        optional_field_info = deepcopy(field.field_info)
        # Do not change default value of fields that are already optional
        if optional_field_info.default is ...:
            optional_field_info.default = None

        field_type = all_annotations.get(field_name, field.outer_type_)
        field_definitions[field_name] = (field_type, optional_field_info)

    return create_model(
        model_name or f'Optional{model.__name__}',
        __base__=model,
        **field_definitions  # type: ignore[arg-type]
    )

Shouldn't field_type be wrapped in typing.Optional?


[FEATURE] Add support for spark processing

We are trying to build lakehouse architecture on AWS S3 using dbtvault and dbt-glue. for this approach we need support with spark processing with dbtvault plugin. Currently, dbtvault only has support for snowflake, bigquery.
Are there any future plans or timelines on this feature?

Hi Alex,
Thank you for the quick response. Could you please direct me toward
documentation regarding dbtvautl usage with databricks or spark preferably?
Thank you. Regards
On Thu, Feb 16, 2023 at 3:47 PM Alex Higgs @.***> wrote:

Hi. Where are you reading that dbtvault only supports BigQuery and
Snowflake please? We currently support Postgres and Databricks as well. You
should be able to use the databricks macros in place of spark
—
Reply to this email directly, view it on GitHub
https://github.com/Datavault-UK/dbtvault/issues/185#issuecomment-1433200036,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AOBFD5YF7H5J43CMWCHEGY3WXY4W7ANCNFSM6AAAAAAU6INLOU
.
You are receiving this because you authored the thread.Message ID:
@.***>

Hi Alex, Thank you for the quick response. Could you please direct me toward documentation regarding dbtvautl usage with databricks or spark preferably? Thank you. Regards
…
On Thu, Feb 16, 2023 at 3:47 PM Alex Higgs @.> wrote: Hi. Where are you reading that dbtvault only supports BigQuery and Snowflake please? We currently support Postgres and Databricks as well. You should be able to use the databricks macros in place of spark — Reply to this email directly, view it on GitHub <#185 (comment)>, or unsubscribe https://github.com/notifications/unsubscribe-auth/AOBFD5YF7H5J43CMWCHEGY3WXY4W7ANCNFSM6AAAAAAU6INLOU . You are receiving this because you authored the thread.Message ID: @.>

There is no databricks specific documentation, as dbtvault uses dbt's multi-dispatch to work cross-platform. You may use dbtvault as-is with a databricks connection for Hubs, Links and Satellites at this time. We will be adding support for more structures in the future


OmniSharp not working with legacy .NET projects on Fedora 36

Issue Description
OmniSharp has recently stopped shipping Mono with its installs. While on most Linux distros this causes no issues, on Fedora 36 this breaks non-SDK-style projects like Unity projects, since Fedora 36 does not ship Mono MSBuild anywhere in its repositories, which is required by OmniSharp for non-SDK-style projects.
Steps to Reproduce

Use Fedora 36 (or any more-or-less recent version)
Open a Unity project or any other non-SDK-style project in VS Code

Expected Behavior
OmniSharp boots up and works as intended.
Actual Behavior
OmniSharp boots up, but reports that no MSBuild has been found.
Logs
OmniSharp log
Starting OmniSharp server at 5/26/2022, 5:03:08 PM
    Target: (project path)
OmniSharp server started with Mono 6.12.0.
Path: /home/artyif/.vscode/extensions/ms-dotnettools.csharp-1.25.0-linux-x64/.omnisharp/1.39.0/omnisharp/OmniSharp.exe
PID: 109682
    Starting OmniSharp on fedora 36.0 (x64)

    Checking the 'DOTNET_ROOT' environment variable to find a .NET SDK

    DotNetPath set to /usr/lib64/dotnet/dotnet

    Located 0 MSBuild instance(s)

Could not locate MSBuild instance to register with OmniSharp.
Environment information
VSCode version: 1.66.2
C# Extension: 1.25.0
Mono Information
        OmniSharp using mono :6.12.0
Dotnet Information
.NET SDK (reflecting any global.json):
 Version:   6.0.105
 Commit:    1c35735293
Runtime Environment:
OS Name:     fedora
OS Version:  36
OS Platform: Linux
RID:         fedora.36-x64
Base Path:   /usr/lib64/dotnet/sdk/6.0.105/
Host (useful for support):
Version: 6.0.5
Commit:  70ae3df4a6
.NET SDKs installed:
6.0.105 [/usr/lib64/dotnet/sdk]
.NET runtimes installed:
Microsoft.AspNetCore.App 6.0.5 [/usr/lib64/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.NETCore.App 6.0.5 [/usr/lib64/dotnet/shared/Microsoft.NETCore.App]
To install additional .NET runtimes or SDKs:
https://aka.ms/dotnet-download

Visual Studio Code Extensions

Extension
Author
Version

csharp
ms-dotnettools
1.25.0

file-downloader
mindaro-dev
1.0.12

gitlens
eamodio
12.0.7

material-product-icons
PKief
1.3.0

unity-debug
Unity
3.0.2

vscodeintellicode
VisualStudioExptTeam
1.2.21

Full framework development now requires you to set omnisharp.useModernNet to false in settings. Please see the announcement at https://github.com/OmniSharp/omnisharp-vscode/issues/5120.
You will also need a complete system install of Mono and MSBuild. Please try the mono-complete package and let me know if that resolves your issue.

Full framework development now requires you to set omnisharp.useModernNet to false in settings. Please see the announcement at #5120.
You will also need a complete system install of Mono and MSBuild. Please try the mono-complete package and let me know if that resolves your issue.

No, it doesn't resolve the issue. The only dependencies mono-complete package installs that I don't have is ibm-data-db2, mono-data-oracle, mono-reactive and mono-locale-extras. And yes, I have omnisharp.useModernNet set to false.

Thanks for checking on that package. I will not pretend I know anything about how these Fedora packages are maintained. Doing a search for a MSBuild package isn't turning up anything for Fedora (https://pkgs.org/search/?q=msbuild). I will keep investigating.

Looks like there is a closed issue for an installable Mono MSBuild package for Fedora - https://github.com/mono/linux-packaging-msbuild/issues/18. One thought is you could convert the Debian or Ubuntu .dep packages to .rpm in order to install MSBuild - https://www.systutorials.com/how-to-install-deb-packages-on-fedora/.

Posting this here from #5120
As I can tell msbuild is installed properly on my system (Fedora 36).
[xxxx@fedora ~]$ dotnet msbuild -ver
Microsoft (R) Build Engine version 17.0.0+c9eb9dd64 for .NET
Copyright (C) Microsoft Corporation. All rights reserved.

<IP_ADDRESS>101

Not sure why Omnisharp can't find it...
EDIT
I got it to work by downgrading the extension to 1.24.4, and adding the following to the settings.json:
"omnisharp.useModernNet": false,
"omnisharp.path": "",
"omnisharp.useGlobalMono": "always",

From here upgrading to 1.25.0 breaks the MSBuild connection again. Seems 1.25.0 is the problem?

@esklarski Mono does not use the dotnet SDK MSBuild. You would need to check msbuild -ver to see if you have a proper install.
bash-3.2$ msbuild -ver
Microsoft (R) Build Engine version 16.6.0 for Mono
Copyright (C) Microsoft Corporation. All rights reserved.

<IP_ADDRESS>01

Perhaps these instructions to install the CentOS mono packages would resolve the issue https://www.mono-project.com/download/stable/#download-lin-centos

"omnisharp.useModernNet": false, only set this one will take effect at 1.25.0, and delete others - "omnisharp.path": "",

@esklarski Mono does not use the dotnet SDK MSBuild. You would need to check msbuild -ver to see if you have a proper install.
bash-3.2$ msbuild -ver
Microsoft (R) Build Engine version 16.6.0 for Mono
Copyright (C) Microsoft Corporation. All rights reserved.

<IP_ADDRESS>01

What Fedora seems to be lacking is a mono-msbuild package similar to https://archlinux.pkgs.org/rolling/archlinux-community-x86_64/mono-msbuild-16.10.1.xamarinxplat.2<IP_ADDRESS>.00-2-x86_64.pkg.tar.zst.html which installs the Mono MSBuild. According to this post (https://blog.timpack.org/fedora-29-and-mono-5) there used to be a msbuild package.

Okay, that answers that.
'msbuild -verreturscommand not found...`

Perhaps these instructions to install the Fedora mono packages would resolve the issue https://www.mono-project.com/download/stable/#download-lin-fedora

I tried this but there were dependancy conflicts and I know nothing about resolving those. I'll be looking into this, but I will also try talking to a Fedora person about the dotnet package.

So I don't think the mono-project thing is going to work...
Error:
 Problem: conflicting requests
  - package mono-complete-<IP_ADDRESS>8-0.xamarin.3.epel8.x86_64 requires mono-devel = <IP_ADDRESS>8, but none of the providers can be installed
  - package mono-complete-<IP_ADDRESS>-0.xamarin.1.epel8.x86_64 requires mono-devel = <IP_ADDRESS>, but none of the providers can be installed
  - package mono-complete-<IP_ADDRESS>-0.xamarin.1.epel8.x86_64 requires mono-devel = <IP_ADDRESS>, but none of the providers can be installed
  - package mono-complete-<IP_ADDRESS>-0.xamarin.3.epel8.x86_64 requires mono-devel = <IP_ADDRESS>, but none of the providers can be installed
  - package mono-complete-<IP_ADDRESS>-0.xamarin.2.epel8.x86_64 requires mono-devel = <IP_ADDRESS>, but none of the providers can be installed
  - package mono-complete-<IP_ADDRESS>3-0.xamarin.7.epel8.x86_64 requires mono-devel = <IP_ADDRESS>3, but none of the providers can be installed
  - package mono-complete-<IP_ADDRESS>9-0.xamarin.1.epel8.x86_64 requires mono-devel = <IP_ADDRESS>9, but none of the providers can be installed
  - package mono-complete-<IP_ADDRESS>7-0.xamarin.1.epel8.x86_64 requires mono-devel = <IP_ADDRESS>7, but none of the providers can be installed
  - package mono-complete-<IP_ADDRESS>4-0.xamarin.1.epel8.x86_64 requires mono-devel = <IP_ADDRESS>4, but none of the providers can be installed
  - package mono-complete-<IP_ADDRESS>-0.xamarin.17.epel8.x86_64 requires mono-devel = <IP_ADDRESS>, but none of the providers can be installed
  - package mono-complete-<IP_ADDRESS>-0.xamarin.9.epel8.x86_64 requires mono-devel = <IP_ADDRESS>, but none of the providers can be installed
  - package mono-complete-<IP_ADDRESS>-0.xamarin.3.epel8.x86_64 requires mono-devel = <IP_ADDRESS>, but none of the providers can be installed
  - package mono-complete-<IP_ADDRESS>-0.xamarin.3.epel8.x86_64 requires mono-devel = <IP_ADDRESS>, but none of the providers can be installed
  - package mono-complete-<IP_ADDRESS>-0.xamarin.6.epel8.x86_64 requires mono-devel = <IP_ADDRESS>, but none of the providers can be installed
  - package mono-complete-<IP_ADDRESS>-0.xamarin.3.epel8.x86_64 requires mono-devel = <IP_ADDRESS>, but none of the providers can be installed
  - package mono-complete-<IP_ADDRESS>-0.xamarin.2.epel8.x86_64 requires mono-devel = <IP_ADDRESS>, but none of the providers can be installed
  - package mono-complete-<IP_ADDRESS>-0.xamarin.3.epel8.x86_64 requires mono-devel = <IP_ADDRESS>, but none of the providers can be installed
  - package mono-devel-<IP_ADDRESS>8-0.xamarin.3.epel8.x86_64 requires libgdiplus-devel, but none of the providers can be installed
  - package mono-devel-<IP_ADDRESS>-0.xamarin.1.epel8.x86_64 requires libgdiplus-devel, but none of the providers can be installed
  - package mono-devel-<IP_ADDRESS>-0.xamarin.1.epel8.x86_64 requires libgdiplus-devel, but none of the providers can be installed
  - package mono-devel-<IP_ADDRESS>-0.xamarin.3.epel8.x86_64 requires libgdiplus-devel, but none of the providers can be installed
  - package mono-devel-<IP_ADDRESS>-0.xamarin.2.epel8.x86_64 requires libgdiplus-devel, but none of the providers can be installed
  - package mono-devel-<IP_ADDRESS>3-0.xamarin.7.epel8.x86_64 requires libgdiplus-devel, but none of the providers can be installed
  - package mono-devel-<IP_ADDRESS>9-0.xamarin.1.epel8.x86_64 requires libgdiplus-devel, but none of the providers can be installed
  - package mono-devel-<IP_ADDRESS>7-0.xamarin.1.epel8.x86_64 requires libgdiplus-devel, but none of the providers can be installed
  - package mono-devel-<IP_ADDRESS>4-0.xamarin.1.epel8.x86_64 requires libgdiplus-devel, but none of the providers can be installed
  - package mono-devel-<IP_ADDRESS>-0.xamarin.17.epel8.x86_64 requires libgdiplus-devel, but none of the providers can be installed
  - package mono-devel-<IP_ADDRESS>-0.xamarin.9.epel8.x86_64 requires libgdiplus-devel, but none of the providers can be installed
  - package mono-devel-<IP_ADDRESS>-0.xamarin.3.epel8.x86_64 requires libgdiplus-devel, but none of the providers can be installed
  - package mono-devel-<IP_ADDRESS>-0.xamarin.3.epel8.x86_64 requires libgdiplus-devel, but none of the providers can be installed
  - package mono-devel-<IP_ADDRESS>-0.xamarin.6.epel8.x86_64 requires libgdiplus-devel, but none of the providers can be installed
  - package mono-devel-<IP_ADDRESS>-0.xamarin.3.epel8.x86_64 requires libgdiplus-devel, but none of the providers can be installed
  - package mono-devel-<IP_ADDRESS>-0.xamarin.2.epel8.x86_64 requires libgdiplus-devel, but none of the providers can be installed
  - package mono-devel-<IP_ADDRESS>-0.xamarin.3.epel8.x86_64 requires libgdiplus-devel, but none of the providers can be installed
  - nothing provides pkgconfig(glib-2.0) needed by libgdiplus-devel-5.6-0.xamarin.2.epel8.x86_64
  - nothing provides pkgconfig(gmodule-2.0) needed by libgdiplus-devel-5.6-0.xamarin.2.epel8.x86_64
  - nothing provides pkgconfig(gthread-2.0) needed by libgdiplus-devel-5.6-0.xamarin.2.epel8.x86_64
  - nothing provides pkgconfig(glib-2.0) needed by libgdiplus-devel-5.6.1-0.xamarin.3.epel8.x86_64
  - nothing provides pkgconfig(gmodule-2.0) needed by libgdiplus-devel-5.6.1-0.xamarin.3.epel8.x86_64
  - nothing provides pkgconfig(gthread-2.0) needed by libgdiplus-devel-5.6.1-0.xamarin.3.epel8.x86_64
  - nothing provides pkgconfig(glib-2.0) needed by libgdiplus-devel-6.0.2-0.xamarin.1.epel8.x86_64
  - nothing provides pkgconfig(gmodule-2.0) needed by libgdiplus-devel-6.0.2-0.xamarin.1.epel8.x86_64
  - nothing provides pkgconfig(gthread-2.0) needed by libgdiplus-devel-6.0.2-0.xamarin.1.epel8.x86_64
  - nothing provides pkgconfig(glib-2.0) needed by libgdiplus-devel-6.0.4-0.xamarin.1.epel8.x86_64
  - nothing provides pkgconfig(gmodule-2.0) needed by libgdiplus-devel-6.0.4-0.xamarin.1.epel8.x86_64
  - nothing provides pkgconfig(gthread-2.0) needed by libgdiplus-devel-6.0.4-0.xamarin.1.epel8.x86_64
  - nothing provides pkgconfig(glib-2.0) needed by libgdiplus-devel-6.0.5-0.xamarin.1.epel8.x86_64
  - nothing provides pkgconfig(gmodule-2.0) needed by libgdiplus-devel-6.0.5-0.xamarin.1.epel8.x86_64
  - nothing provides pkgconfig(gthread-2.0) needed by libgdiplus-devel-6.0.5-0.xamarin.1.epel8.x86_64
(try to add '--skip-broken' to skip uninstallable packages)

¯_(ツ)_/¯

Downgrading to 1.24.x or earlier works as a workaround for now, but is obviously undesired

@esklarski On a fresh Fedora 36 install I ran the following successfully.
sudo su
rpm --import "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF"
su -c 'curl https://download.mono-project.com/repo/centos8-stable.repo | tee /etc/yum.repos.d/mono-centos8-stable.repo'
dnf update
dnf install mono-complete

Then checked the msbuild version
[root@fedora jrobichaud]# msbuild -ver
Microsoft (R) Build Engine version 16.6.0 for Mono
Copyright (C) Microsoft Corporation. All rights reserved.

See terminal output.
[jrobichaud@fedora ~]$ sudo su

We trust you have received the usual lecture from the local System
Administrator. It usually boils down to these three things:

    #1) Respect the privacy of others.
    #2) Think before you type.
    #3) With great power comes great responsibility.

[sudo] password for jrobichaud:
[root@fedora jrobichaud]# rpm --import "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF"
su -c 'curl https://download.mono-project.com/repo/centos8-stable.repo | tee /etc/yum.repos.d/mono-centos8-stable.repo'
dnf update
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   189  100   189    0     0    867      0 --:--:-- --:--:-- --:--:--   866
[mono-centos8-stable]
name=mono-centos8-stable
baseurl=https://download.mono-project.com/repo/centos8-stable/
enabled=1
gpgcheck=1
gpgkey=https://download.mono-project.com/repo/xamarin.gpg
Copr repo for PyCharm owned by phracek           70 kB/s |  84 kB     00:01
Fedora 36 - x86_64                              1.9 MB/s |  85 MB     00:45
Fedora 36 openh264 (From Cisco) - x86_64        1.5 kB/s | 2.5 kB     00:01
Fedora Modular 36 - x86_64                      961 kB/s | 2.4 MB     00:02
Fedora 36 - x86_64 - Updates                    3.3 MB/s |  16 MB     00:04
Fedora Modular 36 - x86_64 - Updates            1.1 MB/s | 2.1 MB     00:01
google-chrome                                   5.7 kB/s | 3.6 kB     00:00
mono-centos8-stable                             910 kB/s | 629 kB     00:00
RPM Fusion for Fedora 36 - Nonfree - NVIDIA Dri 9.7 kB/s |  14 kB     00:01
RPM Fusion for Fedora 36 - Nonfree - Steam      1.2 kB/s | 2.1 kB     00:01
Dependencies resolved.
Nothing to do.
Complete!
[root@fedora jrobichaud]# dnf install mono-complete
Last metadata expiration check: 0:00:28 ago on Thu 02 Jun 2022 06:26:05 PM PDT.
Dependencies resolved.
================================================================================
 Package          Arch   Version                      Repository           Size
================================================================================
Installing:
 mono-complete    x86_64 <IP_ADDRESS>-0.xamarin.9.epel8 mono-centos8-stable 7.2 k
Installing dependencies:
 glib2-devel      x86_64 2.72.1-1.fc36                updates             486 k
 ibm-data-db2     x86_64 <IP_ADDRESS>-0.xamarin.9.epel8 mono-centos8-stable  43 k
 libblkid-devel   x86_64 2.38-0.2.fc36                fedora               17 k
 libffi-devel     x86_64 3.4.2-8.fc36                 fedora               29 k
 libgdiplus-devel x86_64 6.1-2.fc36                   fedora              8.2 k
 libgdiplus0      x86_64 6.0.5-0.xamarin.1.epel8      mono-centos8-stable 638 k
 libmono-2_0-1    x86_64 <IP_ADDRESS>-0.xamarin.9.epel8 mono-centos8-stable 7.1 k
 libmono-2_0-devel
                  x86_64 <IP_ADDRESS>-0.xamarin.9.epel8 mono-centos8-stable  56 k
 libmono-llvm0    x86_64 <IP_ADDRESS>-0.xamarin.9.epel8 mono-centos8-stable 9.8 M
 libmonoboehm-2_0-1
                  x86_64 <IP_ADDRESS>-0.xamarin.9.epel8 mono-centos8-stable 7.6 M
 libmonoboehm-2_0-devel
                  x86_64 <IP_ADDRESS>-0.xamarin.9.epel8 mono-centos8-stable 7.0 k
 libmonosgen-2_0-1
                  x86_64 <IP_ADDRESS>-0.xamarin.9.epel8 mono-centos8-stable 8.3 M
 libmonosgen-2_0-devel
                  x86_64 <IP_ADDRESS>-0.xamarin.9.epel8 mono-centos8-stable  10 k
 libmount-devel   x86_64 2.38-0.2.fc36                fedora               18 k
 libselinux-devel x86_64 3.3-4.fc36                   fedora              113 k
 libsepol-devel   x86_64 3.3-3.fc36                   fedora               40 k
 mono-core        x86_64 <IP_ADDRESS>-0.xamarin.9.epel8 mono-centos8-stable  46 M
 mono-data        x86_64 <IP_ADDRESS>-0.xamarin.9.epel8 mono-centos8-stable 4.4 M
 mono-data-oracle x86_64 <IP_ADDRESS>-0.xamarin.9.epel8 mono-centos8-stable  84 k
 mono-data-sqlite x86_64 <IP_ADDRESS>-0.xamarin.9.epel8 mono-centos8-stable  71 k
 mono-devel       x86_64 <IP_ADDRESS>-0.xamarin.9.epel8 mono-centos8-stable  34 M
 mono-extras      x86_64 <IP_ADDRESS>-0.xamarin.9.epel8 mono-centos8-stable 403 k
 mono-llvm-tools  x86_64 6.0+mono20190708165219-0.xamarin.1.epel8
                                                      mono-centos8-stable  18 M
 mono-locale-extras
                  x86_64 <IP_ADDRESS>-0.xamarin.9.epel8 mono-centos8-stable 295 k
 mono-mvc         x86_64 <IP_ADDRESS>-0.xamarin.9.epel8 mono-centos8-stable 437 k
 mono-reactive    x86_64 <IP_ADDRESS>-0.xamarin.9.epel8 mono-centos8-stable 336 k
 mono-wcf         x86_64 <IP_ADDRESS>-0.xamarin.9.epel8 mono-centos8-stable 978 k
 mono-web         x86_64 <IP_ADDRESS>-0.xamarin.9.epel8 mono-centos8-stable 2.2 M
 mono-winforms    x86_64 <IP_ADDRESS>-0.xamarin.9.epel8 mono-centos8-stable 1.5 M
 mono-winfxcore   x86_64 <IP_ADDRESS>-0.xamarin.9.epel8 mono-centos8-stable 267 k
 monodoc-core     x86_64 <IP_ADDRESS>-0.xamarin.9.epel8 mono-centos8-stable  19 M
 msbuild          noarch 1:16.6+xamarinxplat.2<IP_ADDRESS>.31-0.xamarin.1.epel8
                                                      mono-centos8-stable  10 M
 msbuild-libhostfxr
                  x86_64 <IP_ADDRESS><IP_ADDRESS>.13-0.xamarin.4.epel8
                                                      mono-centos8-stable 158 k
 msbuild-sdkresolver
                  noarch 1:16.6+xamarinxplat.2<IP_ADDRESS>.31-0.xamarin.1.epel8
                                                      mono-centos8-stable  54 k
 pcre-cpp         x86_64 8.45-1.fc36.1                fedora               26 k
 pcre-devel       x86_64 8.45-1.fc36.1                fedora              470 k
 pcre-utf16       x86_64 8.45-1.fc36.1                fedora              187 k
 pcre-utf32       x86_64 8.45-1.fc36.1                fedora              177 k
 pcre2-devel      x86_64 10.40-1.fc36                 updates             474 k
 sysprof-capture-devel
                  x86_64 3.44.0-1.fc36                fedora               66 k
 zlib-devel       x86_64 1.2.11-31.fc36               fedora               44 k

Transaction Summary
================================================================================
Install  42 Packages

Total download size: 167 M
Installed size: 173 M
Is this ok [y/N]: y
Downloading Packages:
(1/42): libgdiplus-devel-6.1-2.fc36.x86_64.rpm   45 kB/s | 8.2 kB     00:00
(2/42): libblkid-devel-2.38-0.2.fc36.x86_64.rpm  82 kB/s |  17 kB     00:00
(3/42): libffi-devel-3.4.2-8.fc36.x86_64.rpm    132 kB/s |  29 kB     00:00
(4/42): libmount-devel-2.38-0.2.fc36.x86_64.rpm 222 kB/s |  18 kB     00:00
(5/42): libsepol-devel-3.3-3.fc36.x86_64.rpm    369 kB/s |  40 kB     00:00
(6/42): pcre-cpp-8.45-1.fc36.1.x86_64.rpm       310 kB/s |  26 kB     00:00
(7/42): libselinux-devel-3.3-4.fc36.x86_64.rpm  619 kB/s | 113 kB     00:00
(8/42): pcre-utf16-8.45-1.fc36.1.x86_64.rpm     1.1 MB/s | 187 kB     00:00
(9/42): pcre-utf32-8.45-1.fc36.1.x86_64.rpm     1.2 MB/s | 177 kB     00:00
(10/42): pcre-devel-8.45-1.fc36.1.x86_64.rpm    1.6 MB/s | 470 kB     00:00
(11/42): sysprof-capture-devel-3.44.0-1.fc36.x8 653 kB/s |  66 kB     00:00
(12/42): zlib-devel-1.2.11-31.fc36.x86_64.rpm   431 kB/s |  44 kB     00:00
(13/42): libgdiplus0-6.0.5-0.xamarin.1.epel8.x8 1.2 MB/s | 638 kB     00:00
(14/42): ibm-data-db2-<IP_ADDRESS>-0.xamarin.9.ep 1.0 MB/s |  43 kB     00:00
(15/42): libmono-2_0-1-<IP_ADDRESS>-0.xamarin.9.e 138 kB/s | 7.1 kB     00:00
(16/42): libmono-2_0-devel-<IP_ADDRESS>-0.xamarin 1.1 MB/s |  56 kB     00:00
(17/42): glib2-devel-2.72.1-1.fc36.x86_64.rpm   342 kB/s | 486 kB     00:01
(18/42): libmono-llvm0-<IP_ADDRESS>-0.xamarin.9.e 7.0 MB/s | 9.8 MB     00:01
(19/42): pcre2-devel-10.40-1.fc36.x86_64.rpm    200 kB/s | 474 kB     00:02
(20/42): libmonoboehm-2_0-devel-<IP_ADDRESS>-0.xa 8.8 kB/s | 7.0 kB     00:00
(21/42): libmonoboehm-2_0-1-<IP_ADDRESS>-0.xamari 4.4 MB/s | 7.6 MB     00:01
(22/42): libmonosgen-2_0-devel-<IP_ADDRESS>-0.xam  12 kB/s |  10 kB     00:00
(23/42): mono-complete-<IP_ADDRESS>-0.xamarin.9.e 8.5 kB/s | 7.2 kB     00:00
(24/42): libmonosgen-2_0-1-<IP_ADDRESS>-0.xamarin 4.3 MB/s | 8.3 MB     00:01
(25/42): mono-data-oracle-<IP_ADDRESS>-0.xamarin. 105 kB/s |  84 kB     00:00
(26/42): mono-data-sqlite-<IP_ADDRESS>-0.xamarin.  85 kB/s |  71 kB     00:00
(27/42): mono-data-<IP_ADDRESS>-0.xamarin.9.epel8 1.9 MB/s | 4.4 MB     00:02
(28/42): mono-extras-<IP_ADDRESS>-0.xamarin.9.epe 430 kB/s | 403 kB     00:00
(29/42): mono-locale-extras-<IP_ADDRESS>-0.xamari 361 kB/s | 295 kB     00:00
(30/42): mono-mvc-<IP_ADDRESS>-0.xamarin.9.epel8. 486 kB/s | 437 kB     00:00
(31/42): mono-reactive-<IP_ADDRESS>-0.xamarin.9.e 404 kB/s | 336 kB     00:00
(32/42): mono-wcf-<IP_ADDRESS>-0.xamarin.9.epel8. 743 kB/s | 978 kB     00:01
(33/42): mono-web-<IP_ADDRESS>-0.xamarin.9.epel8. 1.5 MB/s | 2.2 MB     00:01
(34/42): mono-core-<IP_ADDRESS>-0.xamarin.9.epel8 4.4 MB/s |  46 MB     00:10
(35/42): mono-winforms-<IP_ADDRESS>-0.xamarin.9.e 770 kB/s | 1.5 MB     00:01
(36/42): mono-winfxcore-<IP_ADDRESS>-0.xamarin.9. 250 kB/s | 267 kB     00:01
(37/42): mono-devel-<IP_ADDRESS>-0.xamarin.9.epel 3.3 MB/s |  34 MB     00:10
[MIRROR] monodoc-core-<IP_ADDRESS>-0.xamarin.9.epel8.x86_64.rpm: Curl error (56): Failure when receiving data from the peer for https://download.mono-project.com/repo/centos8-stable/m/mono-core/monodoc-core-<IP_ADDRESS>-0.xamarin.9.epel8.x86_64.rpm [OpenSSL SSL_read: SSL_ERROR_SYSCALL, errno 0]
(38/42): msbuild-libhostfxr-<IP_ADDRESS><IP_ADDRESS> 148 kB/s | 158 kB     00:01
(39/42): msbuild-16.6+xamarinxplat.2<IP_ADDRESS> 2.4 MB/s |  10 MB     00:04
(40/42): monodoc-core-<IP_ADDRESS>-0.xamarin.9.ep 2.5 MB/s |  19 MB     00:07
(41/42): mono-llvm-tools-6.0+mono20190708165219 2.5 MB/s |  18 MB     00:07
(42/42): msbuild-sdkresolver-16.6+xamarinxplat.  51 kB/s |  54 kB     00:01
--------------------------------------------------------------------------------
Total                                           6.9 MB/s | 167 MB     00:24
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.

Copyright 2002, 2003 Motus Technologies. Copyright 2004-2008 Novell. BSD licensed.

Importing into legacy system store:
I already trust 0, your new list has 131
Certificate added: CN=ACCVRAIZ1, OU=PKIACCV, O=ACCV, C=ES
Certificate added: C=ES, O=FNMT-RCM, OU=AC RAIZ FNMT-RCM
Certificate added: C=ES, O=FNMT-RCM, OU=Ceres, OID.<IP_ADDRESS>=VATES-Q2826004J, CN=AC RAIZ FNMT-RCM SERVIDORES SEGUROS
Certificate added: SERIALNUMBER=G63287510, C=ES, O=ANF Autoridad de Certificacion, OU=ANF CA Raiz, CN=ANF Secure Server Root CA
Certificate added: C=IT, L=Milan, O=Actalis S.p.A./03358520967, CN=Actalis Authentication Root CA
Certificate added: C=US, O=AffirmTrust, CN=AffirmTrust Commercial
Certificate added: C=US, O=AffirmTrust, CN=AffirmTrust Networking
Certificate added: C=US, O=AffirmTrust, CN=AffirmTrust Premium
Certificate added: C=US, O=AffirmTrust, CN=AffirmTrust Premium ECC
Certificate added: C=US, O=Amazon, CN=Amazon Root CA 1
Certificate added: C=US, O=Amazon, CN=Amazon Root CA 2
Certificate added: C=US, O=Amazon, CN=Amazon Root CA 3
Certificate added: C=US, O=Amazon, CN=Amazon Root CA 4
Certificate added: CN=Atos TrustedRoot 2011, O=Atos, C=DE
Certificate added: C=ES, CN=Autoridad de Certificacion Firmaprofesional CIF A62634068
Certificate added: C=IE, O=Baltimore, OU=CyberTrust, CN=Baltimore CyberTrust Root
Certificate added: C=NO, O=Buypass AS-983163327, CN=Buypass Class 2 Root CA
Certificate added: C=NO, O=Buypass AS-983163327, CN=Buypass Class 3 Root CA
Certificate added: C=SK, L=Bratislava, O=Disig a.s., CN=CA Disig Root R2
Certificate added: C=CN, O=China Financial Certification Authority, CN=CFCA EV ROOT
Certificate added: C=GB, S=Greater Manchester, L=Salford, O=COMODO CA Limited, CN=COMODO Certification Authority
Certificate added: C=GB, S=Greater Manchester, L=Salford, O=COMODO CA Limited, CN=COMODO ECC Certification Authority
Certificate added: C=GB, S=Greater Manchester, L=Salford, O=COMODO CA Limited, CN=COMODO RSA Certification Authority
Certificate added: C=FR, O=Dhimyotis, CN=Certigna
Certificate added: C=FR, O=Dhimyotis, OU=0002<PHONE_NUMBER>0036, CN=Certigna Root CA
Certificate added: C=PL, O=Asseco Data Systems S.A., OU=Certum Certification Authority, CN=Certum EC-384 CA
Certificate added: C=PL, O=Unizeto Technologies S.A., OU=Certum Certification Authority, CN=Certum Trusted Network CA
Certificate added: C=PL, O=Unizeto Technologies S.A., OU=Certum Certification Authority, CN=Certum Trusted Network CA 2
Certificate added: C=PL, O=Asseco Data Systems S.A., OU=Certum Certification Authority, CN=Certum Trusted Root CA
Certificate added: C=GB, S=Greater Manchester, L=Salford, O=Comodo CA Limited, CN=AAA Certificate Services
Certificate added: O="Cybertrust, Inc", CN=Cybertrust Global Root
Certificate added: C=DE, O=D-Trust GmbH, CN=D-TRUST Root Class 3 CA 2 2009
Certificate added: C=DE, O=D-Trust GmbH, CN=D-TRUST Root Class 3 CA 2 EV 2009
Certificate added: O=Digital Signature Trust Co., CN=DST Root CA X3
Certificate added: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Assured ID Root CA
Certificate added: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Assured ID Root G2
Certificate added: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Assured ID Root G3
Certificate added: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Global Root CA
Certificate added: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Global Root G2
Certificate added: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Global Root G3
Certificate added: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert High Assurance EV Root CA
Certificate added: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Trusted Root G4
Certificate added: C=TR, L=Ankara, O=E-Tuğra EBG Bilişim Teknolojileri ve Hizmetleri A.Ş., OU=E-Tugra Sertifikasyon Merkezi, CN=E-Tugra Certification Authority
Certificate added: C=ES, O=Agencia Catalana de Certificacio (NIF Q-0801176-I), OU=Serveis Publics de Certificacio, OU=Vegeu https://www.catcert.net/verarrel (c)03, OU=Jerarquia Entitats de Certificacio Catalanes, CN=EC-ACC
Certificate added: O=Entrust.net, OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.), OU=(c) 1999 Entrust.net Limited, CN=Entrust.net Certification Authority (2048)
Certificate added: C=US, O="Entrust, Inc.", OU=www.entrust.net/CPS is incorporated by reference, OU="(c) 2006 Entrust, Inc.", CN=Entrust Root Certification Authority
Certificate added: C=US, O="Entrust, Inc.", OU=See www.entrust.net/legal-terms, OU="(c) 2012 Entrust, Inc. - for authorized use only", CN=Entrust Root Certification Authority - EC1
Certificate added: C=US, O="Entrust, Inc.", OU=See www.entrust.net/legal-terms, OU="(c) 2009 Entrust, Inc. - for authorized use only", CN=Entrust Root Certification Authority - G2
Certificate added: C=US, O="Entrust, Inc.", OU=See www.entrust.net/legal-terms, OU="(c) 2015 Entrust, Inc. - for authorized use only", CN=Entrust Root Certification Authority - G4
Certificate added: C=CN, O="GUANG DONG CERTIFICATE AUTHORITY CO.,LTD.", CN=GDCA TrustAUTH R5 ROOT
Certificate added: C=AT, O=e-commerce monitoring GmbH, CN=GLOBALTRUST 2020
Certificate added: C=US, O=Google Trust Services LLC, CN=GTS Root R1
Certificate added: C=US, O=Google Trust Services LLC, CN=GTS Root R2
Certificate added: C=US, O=Google Trust Services LLC, CN=GTS Root R3
Certificate added: C=US, O=Google Trust Services LLC, CN=GTS Root R4
Certificate added: OU=GlobalSign ECC Root CA - R4, O=GlobalSign, CN=GlobalSign
Certificate added: OU=GlobalSign ECC Root CA - R5, O=GlobalSign, CN=GlobalSign
Certificate added: C=BE, O=GlobalSign nv-sa, OU=Root CA, CN=GlobalSign Root CA
Certificate added: OU=GlobalSign Root CA - R2, O=GlobalSign, CN=GlobalSign
Certificate added: OU=GlobalSign Root CA - R3, O=GlobalSign, CN=GlobalSign
Certificate added: OU=GlobalSign Root CA - R6, O=GlobalSign, CN=GlobalSign
Certificate added: C=BE, O=GlobalSign nv-sa, CN=GlobalSign Root E46
Certificate added: C=BE, O=GlobalSign nv-sa, CN=GlobalSign Root R46
Certificate added: C=US, O="The Go Daddy Group, Inc.", OU=Go Daddy Class 2 Certification Authority
Certificate added: C=US, S=Arizona, L=Scottsdale, O="GoDaddy.com, Inc.", CN=Go Daddy Root Certificate Authority - G2
Certificate added: C=GR, O=Hellenic Academic and Research Institutions CA, CN=HARICA TLS ECC Root CA 2021
Certificate added: C=GR, O=Hellenic Academic and Research Institutions CA, CN=HARICA TLS RSA Root CA 2021
Certificate added: C=GR, L=Athens, O=Hellenic Academic and Research Institutions Cert. Authority, CN=Hellenic Academic and Research Institutions ECC RootCA 2015
Certificate added: C=GR, O=Hellenic Academic and Research Institutions Cert. Authority, CN=Hellenic Academic and Research Institutions RootCA 2011
Certificate added: C=GR, L=Athens, O=Hellenic Academic and Research Institutions Cert. Authority, CN=Hellenic Academic and Research Institutions RootCA 2015
Certificate added: C=HK, O=Hongkong Post, CN=Hongkong Post Root CA 1
Certificate added: C=HK, S=Hong Kong, L=Hong Kong, O=Hongkong Post, CN=Hongkong Post Root CA 3
Certificate added: C=US, O=Internet Security Research Group, CN=ISRG Root X1
Certificate added: C=US, O=IdenTrust, CN=IdenTrust Commercial Root CA 1
Certificate added: C=US, O=IdenTrust, CN=IdenTrust Public Sector Root CA 1
Certificate added: C=ES, O=IZENPE S.A., CN=Izenpe.com
Certificate added: C=HU, L=Budapest, O=Microsec Ltd., CN=Microsec e-Szigno Root CA 2009<EMAIL_ADDRESS>Certificate added: C=US, O=Microsoft Corporation, CN=Microsoft ECC Root Certificate Authority 2017
Certificate added: C=US, O=Microsoft Corporation, CN=Microsoft RSA Root Certificate Authority 2017
Certificate added: C=KR, O=NAVER BUSINESS PLATFORM Corp., CN=NAVER Global Root Certification Authority
Certificate added: C=HU, L=Budapest, O=NetLock Kft., OU=Tanúsítványkiadók (Certification Services), CN=NetLock Arany (Class Gold) Főtanúsítvány
Certificate added: C=US, O=Network Solutions L.L.C., CN=Network Solutions Certificate Authority
Certificate added: C=CH, O=WISeKey, OU=OISTE Foundation Endorsed, CN=OISTE WISeKey Global Root GB CA
Certificate added: C=CH, O=WISeKey, OU=OISTE Foundation Endorsed, CN=OISTE WISeKey Global Root GC CA
Certificate added: C=BM, O=QuoVadis Limited, CN=QuoVadis Root CA 1 G3
Certificate added: C=BM, O=QuoVadis Limited, CN=QuoVadis Root CA 2
Certificate added: C=BM, O=QuoVadis Limited, CN=QuoVadis Root CA 2 G3
Certificate added: C=BM, O=QuoVadis Limited, CN=QuoVadis Root CA 3
Certificate added: C=BM, O=QuoVadis Limited, CN=QuoVadis Root CA 3 G3
Certificate added: C=US, S=Texas, L=Houston, O=SSL Corporation, CN=SSL.com EV Root Certification Authority ECC
Certificate added: C=US, S=Texas, L=Houston, O=SSL Corporation, CN=SSL.com EV Root Certification Authority RSA R2
Certificate added: C=US, S=Texas, L=Houston, O=SSL Corporation, CN=SSL.com Root Certification Authority ECC
Certificate added: C=US, S=Texas, L=Houston, O=SSL Corporation, CN=SSL.com Root Certification Authority RSA
Certificate added: C=PL, O=Krajowa Izba Rozliczeniowa S.A., CN=SZAFIR ROOT CA2
Certificate added: C=JP, O="Japan Certification Services, Inc.", CN=SecureSign RootCA11
Certificate added: C=US, O=SecureTrust Corporation, CN=SecureTrust CA
Certificate added: C=US, O=SecureTrust Corporation, CN=Secure Global CA
Certificate added: C=JP, O="SECOM Trust Systems CO.,LTD.", OU=Security Communication RootCA2
Certificate added: C=JP, O=SECOM Trust.net, OU=Security Communication RootCA1
Certificate added: C=NL, O=Staat der Nederlanden, CN=Staat der Nederlanden EV Root CA
Certificate added: C=US, O="Starfield Technologies, Inc.", OU=Starfield Class 2 Certification Authority
Certificate added: C=US, S=Arizona, L=Scottsdale, O="Starfield Technologies, Inc.", CN=Starfield Root Certificate Authority - G2
Certificate added: C=US, S=Arizona, L=Scottsdale, O="Starfield Technologies, Inc.", CN=Starfield Services Root Certificate Authority - G2
Certificate added: C=CH, O=SwissSign AG, CN=SwissSign Gold CA - G2
Certificate added: C=CH, O=SwissSign AG, CN=SwissSign Silver CA - G2
Certificate added: C=DE, O=T-Systems Enterprise Services GmbH, OU=T-Systems Trust Center, CN=T-TeleSec GlobalRoot Class 2
Certificate added: C=DE, O=T-Systems Enterprise Services GmbH, OU=T-Systems Trust Center, CN=T-TeleSec GlobalRoot Class 3
Certificate added: C=TR, L=Gebze - Kocaeli, O=Turkiye Bilimsel ve Teknolojik Arastirma Kurumu - TUBITAK, OU=Kamu Sertifikasyon Merkezi - Kamu SM, CN=TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1
Certificate added: C=TW, O=TAIWAN-CA, OU=Root CA, CN=TWCA Global Root CA
Certificate added: C=TW, O=TAIWAN-CA, OU=Root CA, CN=TWCA Root Certification Authority
Certificate added: O=TeliaSonera, CN=TeliaSonera Root CA v1
Certificate added: C=PA, S=Panama, L=Panama City, O=TrustCor Systems S. de R.L., OU=TrustCor Certificate Authority, CN=TrustCor ECA-1
Certificate added: C=PA, S=Panama, L=Panama City, O=TrustCor Systems S. de R.L., OU=TrustCor Certificate Authority, CN=TrustCor RootCert CA-1
Certificate added: C=PA, S=Panama, L=Panama City, O=TrustCor Systems S. de R.L., OU=TrustCor Certificate Authority, CN=TrustCor RootCert CA-2
Certificate added: C=US, S=Illinois, L=Chicago, O="Trustwave Holdings, Inc.", CN=Trustwave Global Certification Authority
Certificate added: C=US, S=Illinois, L=Chicago, O="Trustwave Holdings, Inc.", CN=Trustwave Global ECC P256 Certification Authority
Certificate added: C=US, S=Illinois, L=Chicago, O="Trustwave Holdings, Inc.", CN=Trustwave Global ECC P384 Certification Authority
Certificate added: C=TN, O=Agence Nationale de Certification Electronique, CN=TunTrust Root CA
Certificate added: C=CN, O=UniTrust, CN=UCA Extended Validation Root
Certificate added: C=CN, O=UniTrust, CN=UCA Global G2 Root
Certificate added: C=US, S=New Jersey, L=Jersey City, O=The USERTRUST Network, CN=USERTrust ECC Certification Authority
Certificate added: C=US, S=New Jersey, L=Jersey City, O=The USERTRUST Network, CN=USERTrust RSA Certification Authority
Certificate added: C=US, OU=www.xrampsecurity.com, O=XRamp Security Services Inc, CN=XRamp Global Certification Authority
Certificate added: C=RO, O=certSIGN, OU=certSIGN ROOT CA
Certificate added: C=RO, O=CERTSIGN SA, OU=certSIGN ROOT CA G2
Certificate added: C=HU, L=Budapest, O=Microsec Ltd., OID.<IP_ADDRESS>=VATHU-23584497, CN=e-Szigno Root CA 2017
Certificate added: C=TW, O="Chunghwa Telecom Co., Ltd.", OU=ePKI Root Certification Authority
Certificate added: C=US, OU=emSign PKI, O=eMudhra Inc, CN=emSign ECC Root CA - C3
Certificate added: C=IN, OU=emSign PKI, O=eMudhra Technologies Limited, CN=emSign ECC Root CA - G3
Certificate added: C=US, OU=emSign PKI, O=eMudhra Inc, CN=emSign Root CA - C1
Certificate added: C=IN, OU=emSign PKI, O=eMudhra Technologies Limited, CN=emSign Root CA - G1
131 new root certificates were added to your trust store.
Import process completed.

Importing into BTLS system store:
I already trust 0, your new list has 131
Certificate added: CN=ACCVRAIZ1, OU=PKIACCV, O=ACCV, C=ES
Certificate added: C=ES, O=FNMT-RCM, OU=AC RAIZ FNMT-RCM
Certificate added: C=ES, O=FNMT-RCM, OU=Ceres, OID.<IP_ADDRESS>=VATES-Q2826004J, CN=AC RAIZ FNMT-RCM SERVIDORES SEGUROS
Certificate added: SERIALNUMBER=G63287510, C=ES, O=ANF Autoridad de Certificacion, OU=ANF CA Raiz, CN=ANF Secure Server Root CA
Certificate added: C=IT, L=Milan, O=Actalis S.p.A./03358520967, CN=Actalis Authentication Root CA
Certificate added: C=US, O=AffirmTrust, CN=AffirmTrust Commercial
Certificate added: C=US, O=AffirmTrust, CN=AffirmTrust Networking
Certificate added: C=US, O=AffirmTrust, CN=AffirmTrust Premium
Certificate added: C=US, O=AffirmTrust, CN=AffirmTrust Premium ECC
Certificate added: C=US, O=Amazon, CN=Amazon Root CA 1
Certificate added: C=US, O=Amazon, CN=Amazon Root CA 2
Certificate added: C=US, O=Amazon, CN=Amazon Root CA 3
Certificate added: C=US, O=Amazon, CN=Amazon Root CA 4
Certificate added: CN=Atos TrustedRoot 2011, O=Atos, C=DE
Certificate added: C=ES, CN=Autoridad de Certificacion Firmaprofesional CIF A62634068
Certificate added: C=IE, O=Baltimore, OU=CyberTrust, CN=Baltimore CyberTrust Root
Certificate added: C=NO, O=Buypass AS-983163327, CN=Buypass Class 2 Root CA
Certificate added: C=NO, O=Buypass AS-983163327, CN=Buypass Class 3 Root CA
Certificate added: C=SK, L=Bratislava, O=Disig a.s., CN=CA Disig Root R2
Certificate added: C=CN, O=China Financial Certification Authority, CN=CFCA EV ROOT
Certificate added: C=GB, S=Greater Manchester, L=Salford, O=COMODO CA Limited, CN=COMODO Certification Authority
Certificate added: C=GB, S=Greater Manchester, L=Salford, O=COMODO CA Limited, CN=COMODO ECC Certification Authority
Certificate added: C=GB, S=Greater Manchester, L=Salford, O=COMODO CA Limited, CN=COMODO RSA Certification Authority
Certificate added: C=FR, O=Dhimyotis, CN=Certigna
Certificate added: C=FR, O=Dhimyotis, OU=0002<PHONE_NUMBER>0036, CN=Certigna Root CA
Certificate added: C=PL, O=Asseco Data Systems S.A., OU=Certum Certification Authority, CN=Certum EC-384 CA
Certificate added: C=PL, O=Unizeto Technologies S.A., OU=Certum Certification Authority, CN=Certum Trusted Network CA
Certificate added: C=PL, O=Unizeto Technologies S.A., OU=Certum Certification Authority, CN=Certum Trusted Network CA 2
Certificate added: C=PL, O=Asseco Data Systems S.A., OU=Certum Certification Authority, CN=Certum Trusted Root CA
Certificate added: C=GB, S=Greater Manchester, L=Salford, O=Comodo CA Limited, CN=AAA Certificate Services
Certificate added: O="Cybertrust, Inc", CN=Cybertrust Global Root
Certificate added: C=DE, O=D-Trust GmbH, CN=D-TRUST Root Class 3 CA 2 2009
Certificate added: C=DE, O=D-Trust GmbH, CN=D-TRUST Root Class 3 CA 2 EV 2009
Certificate added: O=Digital Signature Trust Co., CN=DST Root CA X3
Certificate added: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Assured ID Root CA
Certificate added: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Assured ID Root G2
Certificate added: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Assured ID Root G3
Certificate added: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Global Root CA
Certificate added: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Global Root G2
Certificate added: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Global Root G3
Certificate added: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert High Assurance EV Root CA
Certificate added: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Trusted Root G4
Certificate added: C=TR, L=Ankara, O=E-Tuğra EBG Bilişim Teknolojileri ve Hizmetleri A.Ş., OU=E-Tugra Sertifikasyon Merkezi, CN=E-Tugra Certification Authority
Certificate added: C=ES, O=Agencia Catalana de Certificacio (NIF Q-0801176-I), OU=Serveis Publics de Certificacio, OU=Vegeu https://www.catcert.net/verarrel (c)03, OU=Jerarquia Entitats de Certificacio Catalanes, CN=EC-ACC
Certificate added: O=Entrust.net, OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.), OU=(c) 1999 Entrust.net Limited, CN=Entrust.net Certification Authority (2048)
Certificate added: C=US, O="Entrust, Inc.", OU=www.entrust.net/CPS is incorporated by reference, OU="(c) 2006 Entrust, Inc.", CN=Entrust Root Certification Authority
Certificate added: C=US, O="Entrust, Inc.", OU=See www.entrust.net/legal-terms, OU="(c) 2012 Entrust, Inc. - for authorized use only", CN=Entrust Root Certification Authority - EC1
Certificate added: C=US, O="Entrust, Inc.", OU=See www.entrust.net/legal-terms, OU="(c) 2009 Entrust, Inc. - for authorized use only", CN=Entrust Root Certification Authority - G2
Certificate added: C=US, O="Entrust, Inc.", OU=See www.entrust.net/legal-terms, OU="(c) 2015 Entrust, Inc. - for authorized use only", CN=Entrust Root Certification Authority - G4
Certificate added: C=CN, O="GUANG DONG CERTIFICATE AUTHORITY CO.,LTD.", CN=GDCA TrustAUTH R5 ROOT
Certificate added: C=AT, O=e-commerce monitoring GmbH, CN=GLOBALTRUST 2020
Certificate added: C=US, O=Google Trust Services LLC, CN=GTS Root R1
Certificate added: C=US, O=Google Trust Services LLC, CN=GTS Root R2
Certificate added: C=US, O=Google Trust Services LLC, CN=GTS Root R3
Certificate added: C=US, O=Google Trust Services LLC, CN=GTS Root R4
Certificate added: OU=GlobalSign ECC Root CA - R4, O=GlobalSign, CN=GlobalSign
Certificate added: OU=GlobalSign ECC Root CA - R5, O=GlobalSign, CN=GlobalSign
Certificate added: C=BE, O=GlobalSign nv-sa, OU=Root CA, CN=GlobalSign Root CA
Certificate added: OU=GlobalSign Root CA - R2, O=GlobalSign, CN=GlobalSign
Certificate added: OU=GlobalSign Root CA - R3, O=GlobalSign, CN=GlobalSign
Certificate added: OU=GlobalSign Root CA - R6, O=GlobalSign, CN=GlobalSign
Certificate added: C=BE, O=GlobalSign nv-sa, CN=GlobalSign Root E46
Certificate added: C=BE, O=GlobalSign nv-sa, CN=GlobalSign Root R46
Certificate added: C=US, O="The Go Daddy Group, Inc.", OU=Go Daddy Class 2 Certification Authority
Certificate added: C=US, S=Arizona, L=Scottsdale, O="GoDaddy.com, Inc.", CN=Go Daddy Root Certificate Authority - G2
Certificate added: C=GR, O=Hellenic Academic and Research Institutions CA, CN=HARICA TLS ECC Root CA 2021
Certificate added: C=GR, O=Hellenic Academic and Research Institutions CA, CN=HARICA TLS RSA Root CA 2021
Certificate added: C=GR, L=Athens, O=Hellenic Academic and Research Institutions Cert. Authority, CN=Hellenic Academic and Research Institutions ECC RootCA 2015
Certificate added: C=GR, O=Hellenic Academic and Research Institutions Cert. Authority, CN=Hellenic Academic and Research Institutions RootCA 2011
Certificate added: C=GR, L=Athens, O=Hellenic Academic and Research Institutions Cert. Authority, CN=Hellenic Academic and Research Institutions RootCA 2015
Certificate added: C=HK, O=Hongkong Post, CN=Hongkong Post Root CA 1
Certificate added: C=HK, S=Hong Kong, L=Hong Kong, O=Hongkong Post, CN=Hongkong Post Root CA 3
Certificate added: C=US, O=Internet Security Research Group, CN=ISRG Root X1
Certificate added: C=US, O=IdenTrust, CN=IdenTrust Commercial Root CA 1
Certificate added: C=US, O=IdenTrust, CN=IdenTrust Public Sector Root CA 1
Certificate added: C=ES, O=IZENPE S.A., CN=Izenpe.com
Certificate added: C=HU, L=Budapest, O=Microsec Ltd., CN=Microsec e-Szigno Root CA 2009<EMAIL_ADDRESS>Certificate added: C=US, O=Microsoft Corporation, CN=Microsoft ECC Root Certificate Authority 2017
Certificate added: C=US, O=Microsoft Corporation, CN=Microsoft RSA Root Certificate Authority 2017
Certificate added: C=KR, O=NAVER BUSINESS PLATFORM Corp., CN=NAVER Global Root Certification Authority
Certificate added: C=HU, L=Budapest, O=NetLock Kft., OU=Tanúsítványkiadók (Certification Services), CN=NetLock Arany (Class Gold) Főtanúsítvány
Certificate added: C=US, O=Network Solutions L.L.C., CN=Network Solutions Certificate Authority
Certificate added: C=CH, O=WISeKey, OU=OISTE Foundation Endorsed, CN=OISTE WISeKey Global Root GB CA
Certificate added: C=CH, O=WISeKey, OU=OISTE Foundation Endorsed, CN=OISTE WISeKey Global Root GC CA
Certificate added: C=BM, O=QuoVadis Limited, CN=QuoVadis Root CA 1 G3
Certificate added: C=BM, O=QuoVadis Limited, CN=QuoVadis Root CA 2
Certificate added: C=BM, O=QuoVadis Limited, CN=QuoVadis Root CA 2 G3
Certificate added: C=BM, O=QuoVadis Limited, CN=QuoVadis Root CA 3
Certificate added: C=BM, O=QuoVadis Limited, CN=QuoVadis Root CA 3 G3
Certificate added: C=US, S=Texas, L=Houston, O=SSL Corporation, CN=SSL.com EV Root Certification Authority ECC
Certificate added: C=US, S=Texas, L=Houston, O=SSL Corporation, CN=SSL.com EV Root Certification Authority RSA R2
Certificate added: C=US, S=Texas, L=Houston, O=SSL Corporation, CN=SSL.com Root Certification Authority ECC
Certificate added: C=US, S=Texas, L=Houston, O=SSL Corporation, CN=SSL.com Root Certification Authority RSA
Certificate added: C=PL, O=Krajowa Izba Rozliczeniowa S.A., CN=SZAFIR ROOT CA2
Certificate added: C=JP, O="Japan Certification Services, Inc.", CN=SecureSign RootCA11
Certificate added: C=US, O=SecureTrust Corporation, CN=SecureTrust CA
Certificate added: C=US, O=SecureTrust Corporation, CN=Secure Global CA
Certificate added: C=JP, O="SECOM Trust Systems CO.,LTD.", OU=Security Communication RootCA2
Certificate added: C=JP, O=SECOM Trust.net, OU=Security Communication RootCA1
Certificate added: C=NL, O=Staat der Nederlanden, CN=Staat der Nederlanden EV Root CA
Certificate added: C=US, O="Starfield Technologies, Inc.", OU=Starfield Class 2 Certification Authority
Certificate added: C=US, S=Arizona, L=Scottsdale, O="Starfield Technologies, Inc.", CN=Starfield Root Certificate Authority - G2
Certificate added: C=US, S=Arizona, L=Scottsdale, O="Starfield Technologies, Inc.", CN=Starfield Services Root Certificate Authority - G2
Certificate added: C=CH, O=SwissSign AG, CN=SwissSign Gold CA - G2
Certificate added: C=CH, O=SwissSign AG, CN=SwissSign Silver CA - G2
Certificate added: C=DE, O=T-Systems Enterprise Services GmbH, OU=T-Systems Trust Center, CN=T-TeleSec GlobalRoot Class 2
Certificate added: C=DE, O=T-Systems Enterprise Services GmbH, OU=T-Systems Trust Center, CN=T-TeleSec GlobalRoot Class 3
Certificate added: C=TR, L=Gebze - Kocaeli, O=Turkiye Bilimsel ve Teknolojik Arastirma Kurumu - TUBITAK, OU=Kamu Sertifikasyon Merkezi - Kamu SM, CN=TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1
Certificate added: C=TW, O=TAIWAN-CA, OU=Root CA, CN=TWCA Global Root CA
Certificate added: C=TW, O=TAIWAN-CA, OU=Root CA, CN=TWCA Root Certification Authority
Certificate added: O=TeliaSonera, CN=TeliaSonera Root CA v1
Certificate added: C=PA, S=Panama, L=Panama City, O=TrustCor Systems S. de R.L., OU=TrustCor Certificate Authority, CN=TrustCor ECA-1
Certificate added: C=PA, S=Panama, L=Panama City, O=TrustCor Systems S. de R.L., OU=TrustCor Certificate Authority, CN=TrustCor RootCert CA-1
Certificate added: C=PA, S=Panama, L=Panama City, O=TrustCor Systems S. de R.L., OU=TrustCor Certificate Authority, CN=TrustCor RootCert CA-2
Certificate added: C=US, S=Illinois, L=Chicago, O="Trustwave Holdings, Inc.", CN=Trustwave Global Certification Authority
Certificate added: C=US, S=Illinois, L=Chicago, O="Trustwave Holdings, Inc.", CN=Trustwave Global ECC P256 Certification Authority
Certificate added: C=US, S=Illinois, L=Chicago, O="Trustwave Holdings, Inc.", CN=Trustwave Global ECC P384 Certification Authority
Certificate added: C=TN, O=Agence Nationale de Certification Electronique, CN=TunTrust Root CA
Certificate added: C=CN, O=UniTrust, CN=UCA Extended Validation Root
Certificate added: C=CN, O=UniTrust, CN=UCA Global G2 Root
Certificate added: C=US, S=New Jersey, L=Jersey City, O=The USERTRUST Network, CN=USERTrust ECC Certification Authority
Certificate added: C=US, S=New Jersey, L=Jersey City, O=The USERTRUST Network, CN=USERTrust RSA Certification Authority
Certificate added: C=US, OU=www.xrampsecurity.com, O=XRamp Security Services Inc, CN=XRamp Global Certification Authority
Certificate added: C=RO, O=certSIGN, OU=certSIGN ROOT CA
Certificate added: C=RO, O=CERTSIGN SA, OU=certSIGN ROOT CA G2
Certificate added: C=HU, L=Budapest, O=Microsec Ltd., OID.<IP_ADDRESS>=VATHU-23584497, CN=e-Szigno Root CA 2017
Certificate added: C=TW, O="Chunghwa Telecom Co., Ltd.", OU=ePKI Root Certification Authority
Certificate added: C=US, OU=emSign PKI, O=eMudhra Inc, CN=emSign ECC Root CA - C3
Certificate added: C=IN, OU=emSign PKI, O=eMudhra Technologies Limited, CN=emSign ECC Root CA - G3
Certificate added: C=US, OU=emSign PKI, O=eMudhra Inc, CN=emSign Root CA - C1
Certificate added: C=IN, OU=emSign PKI, O=eMudhra Technologies Limited, CN=emSign Root CA - G1
131 new root certificates were added to your trust store.
Import process completed.

   All rights reserved.

[root@fedora jrobichaud]#

Okay, I can confirm everything seems to be working properly now. Thanks for the help.
Fedora users beware of orphaned mono packages ;-)

Glad things are working now. Will close this out.

This worked for me:

sudo rpm --import "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF"
su -c 'curl https://download.mono-project.com/repo/centos8-stable.repo | tee /etc/yum.repos.d/mono-centos8-stable.repo'
dnf update
dnf install mono-complete

These steps basically.
Although I had to dnf remove the existing mono-core package otherwise there were problems with dnf update.
But now I'm getting the following error. It seems that the version of mono on my fedora 35 installation does not have the required version of MSBUILD.
[info]: OmniSharp.MSBuild.Discovery.MSBuildLocator
        Located 1 MSBuild instance(s)
            1: Mono 16.6.0 - "/usr/lib/mono/msbuild/Current/bin"
[warn]: OmniSharp.CompositionHostBuilder
        It looks like you have Mono installed which contains a MSBuild lower than 16.7.0 which is the minimum supported by the configured .NET Core Sdk.
 Try updating Mono to the latest stable or preview version to enable better .NET Core Sdk support.

@ccaneke @esklarski @JoeRobich After following those steps, I noticed that I only had msbuild v16.6.0, but I need at least v17.0.0 for a vim plugin I'm using in a Unity Project. Were you ever able to find how to update to a newer version?

@BagelSeasoning234 I believe the latest MSBuild that is shipping with the release Mono is 16.10 (ultimately it depends on your distro). The .NET SDK ships with the latest 17.x MSBuild, however that may not help since last I recall Unity generates Full Framework projects not SDK projects.

@BagelSeasoning234 After doing some snooping, it appears that maybe a community member has written a plugin that will generate SDK style projects for Unity. You could then run with omnisharp.useModernNet set to true against a .NET 6+ SDK.

Alright, thanks! It appears as though the immediate issue I was having with the vim plugin was caused by another problem that I was able to resolve, but given that I still get warning messages about updating msbuild, I will make sure to look into that if I have any additional issues.


When reading ObjC class table, use new SPI if it is avail

When reading ObjC class table, use new SPI if it is avail
In the latest OS betas, the objc runtime has a special interface
for the debugger, class_getNameRaw(), instead of the existing
class_getName(), which will return class names in their raw, unmangled
(in the case of swift) form.  When lldb can access the unmangled
names of classes, it won't need to fetch them out of the inferior
process after we run our "get the objc class table" expression.
If the new interface is absent (debugging a process on an older
target), lldb will fall back to class_getName and reading any class
names that it got back in demangled form, at a bit of a performance
cost on the first expression.
on llvm.org in r363103.
rdar://problem/50688054

@swift-ci test and merge

This broke the windows build! https://dev.azure.com/compnerd/windows-swift/_build/results?buildId=3116
CC: @adrian-prantl @dcci @JDevlieghere

This was also reverted upstream in SVN r363115


Check if cell is updateable

Describe what did you try to do with TM1py
I'm loading data through a cellset (as a user, not ADMIN), but some of the cells are not editable.
Which cells are not editable can't be defined upfront as it changes dynamically due to rules and security being dependent on time dimension.
Describe what's not working the way you expect
I would like to have an option/argument in write functions to skip noneditable cells similar to what can be achieved using
CELLISUDATEABLE tm1 function.
Version

TM1py: 1.6.0
TM1 Server Version: 11.0.8

Additional context
N/A

Hi @macmaj,
You have to write custom logic to solve this problem. To know if a cell is editable you can execute an MDX and ask for the RuleDerived, Consolidated and Updateable properties.
So essentially, based on your cellset you create an MDX to find the cells that are not editable in TM1.
Then you remove those cells from your cellset and write the rest of the cells to TM1.
Kinda like this:
from mdxpy import MdxBuilder

from TM1py import TM1Service
from TM1py.Utils import cell_is_updateable, element_names_from_element_unique_names

cells = {
    ('Total', 'Total'): 1,
    ('e1', 'e1'): 1,
    ('e2', 'e2'): 1,
    ('e3', 'e3'): 1}

query = MdxBuilder.from_cube('c1')
for elements in cells:
    member_tuple = [f"[d1].[{elements[0]}]", f"[d2].[{elements[1]}]"]
    query.add_member_tuple_to_columns(*member_tuple)

with TM1Service(address="", port=12354, ssl=True, user="admin", password="apple") as tm1:
    data = tm1.cells.execute_mdx(
        mdx=query.to_mdx(),
        cell_properties=['Value', 'Updateable', 'RuleDerived', 'Consolidated'])

    for coordinates, cell in data.items():
        if cell['RuleDerived'] or cell['Consolidated'] or not cell_is_updateable(cell):
            del cells[element_names_from_element_unique_names(coordinates)]

    tm1.cells.write(cube_name='c1', cellset_as_dict=cells)

Hi @MariusWirtz
Thanks a lot, this is exactly what I was looking for.