show 316 results

Blog entries

  • Typing Mercurial with pytype

    2019/11/14 by Denis Laxalde

    Following the recent introduction of Python type annotations (aka "type hints") in Mercurial (see, e.g. this changeset by Augie Fackler), I've been playing a bit with this and pytype.

    pytype is a static type analyzer for Python code. It compares with the more popular mypy but I don't have enough perspective to make a meaningful comparison at the moment. In this post, I'll illustrate how I worked with pytype to gradually add type hints in a Mercurial module and while doing so, fix bugs!

    The module I focused on is mercurial.mail, which contains mail utilities and that I know quite well. Other modules are also being worked on, this one is a good starting point because it has a limited number of "internal" dependencies, which both makes it faster to iterate with pytype and reduces side effects of other modules not being correctly typed already.

    $ pytype mercurial/mail.py
    Computing dependencies
    Analyzing 1 sources with 36 local dependencies
    ninja: Entering directory `.pytype'
    [19/19] check mercurial.mail
    Success: no errors found
    

    The good news is that the module apparently already type-checks. Let's go deeper and merge the type annotations generated by pytype:

    $ merge-pyi -i mercurial/mail.py out/mercurial/mail.pyi
    

    (In practice, we'd use --as-comments option to write type hints as comments, so that the module is still usable on Python 2.)

    Now we have all declarations annotated with types. Typically, we'd get many things like:

    def codec2iana(cs) -> Any:
       cs = pycompat.sysbytes(email.charset.Charset(cs).input_charset.lower())
       # "latin1" normalizes to "iso8859-1", standard calls for "iso-8859-1"
       if cs.startswith(b"iso") and not cs.startswith(b"iso-"):
          return b"iso-" + cs[3:]
       return cs
    

    The function signature has been annotated with Any (omitted for parameters, explicit for return value). This somehow means that type inference failed to find the type of that function. As it's (quite) obvious, let's change that into:

    def codec2iana(cs: bytes) -> bytes:
       ...
    

    And re-run pytype:

    $ pytype mercurial/mail.py
    Computing dependencies
    Analyzing 1 sources with 36 local dependencies
    ninja: Entering directory `.pytype'
    [1/1] check mercurial.mail
    FAILED: .pytype/pyi/mercurial/mail.pyi
    pytype-single --imports_info .pytype/imports/mercurial.mail.imports --module-name mercurial.mail -V 3.7 -o .pytype/pyi/mercurial/mail.pyi --analyze-annotated --nofail --quick mercurial/mail.py
    File "mercurial/mail.py", line 253, in codec2iana: Function Charset.__init__ was called with the wrong arguments [wrong-arg-types]
      Expected: (self, input_charset: str = ...)
      Actually passed: (self, input_charset: bytes)
    
    For more details, see https://google.github.io/pytype/errors.html#wrong-arg-types.
    ninja: build stopped: subcommand failed.
    

    Interesting! email.charset.Charset is apparently instantiated with the wrong argument type. While it's not exactly a bug, because Python will handle bytes instead of str well in general, we can again change the signature (and code) to:

    def codec2iana(cs: str) -> str:
       cs = email.charset.Charset(cs).input_charset.lower()
       # "latin1" normalizes to "iso8859-1", standard calls for "iso-8859-1"
       if cs.startswith("iso") and not cs.startswith("iso-"):
          return "iso-" + cs[3:]
       return cs
    

    Obviously, this involves a larger refactoring in client code of this simple function, see respective changeset for details.

    Another example is this function:

    def _encode(ui, s, charsets) -> Any:
        '''Returns (converted) string, charset tuple.
        Finds out best charset by cycling through sendcharsets in descending
        order. Tries both encoding and fallbackencoding for input. Only as
        last resort send as is in fake ascii.
        Caveat: Do not use for mail parts containing patches!'''
        sendcharsets = charsets or _charsets(ui)
        if not isinstance(s, bytes):
            # We have unicode data, which we need to try and encode to
            # some reasonable-ish encoding. Try the encodings the user
            # wants, and fall back to garbage-in-ascii.
            for ocs in sendcharsets:
                try:
                    return s.encode(pycompat.sysstr(ocs)), ocs
                except UnicodeEncodeError:
                    pass
                except LookupError:
                    ui.warn(_(b'ignoring invalid sendcharset: %s\n') % ocs)
            else:
                # Everything failed, ascii-armor what we've got and send it.
                return s.encode('ascii', 'backslashreplace')
        # We have a bytes of unknown encoding. We'll try and guess a valid
        # encoding, falling back to pretending we had ascii even though we
        # know that's wrong.
        try:
            s.decode('ascii')
        except UnicodeDecodeError:
            for ics in (encoding.encoding, encoding.fallbackencoding):
                ics = pycompat.sysstr(ics)
                try:
                    u = s.decode(ics)
                except UnicodeDecodeError:
                    continue
                for ocs in sendcharsets:
                    try:
                        return u.encode(pycompat.sysstr(ocs)), ocs
                    except UnicodeEncodeError:
                        pass
                    except LookupError:
                        ui.warn(_(b'ignoring invalid sendcharset: %s\n') % ocs)
        # if ascii, or all conversion attempts fail, send (broken) ascii
        return s, b'us-ascii'
    

    It quite clear from the return value (last line) that we can change its type signature to:

    def _encode(ui, s:Union[bytes, str], charsets: List[bytes]) -> Tuple[bytes, bytes]
       ...
    

    And re-run pytype:

    $ pytype mercurial/mail.py
    Computing dependencies
    Analyzing 1 sources with 36 local dependencies
    ninja: Entering directory `.pytype'
    [1/1] check mercurial.mail
    FAILED: .pytype/pyi/mercurial/mail.pyi
    pytype-single --imports_info .pytype/imports/mercurial.mail.imports --module-name mercurial.mail -V 3.7 -o .pytype/pyi/mercurial/mail.pyi --analyze-annotated --nofail --quick mercurial/mail.py
    File "mercurial/mail.py", line 342, in _encode: bad option in return type [bad-return-type]
      Expected: Tuple[bytes, bytes]
      Actually returned: bytes
    [...]
    
    For more details, see https://google.github.io/pytype/errors.html.
    ninja: build stopped: subcommand failed.
    

    That's a real bug. Line 371 contains return s.encode('ascii', 'backslashreplace') in the middle of the function. We indeed return a bytes value instead of a Tuple[bytes, bytes] as elsewhere in the function. The following changes fixes the bug:

    diff --git a/mercurial/mail.py b/mercurial/mail.py
    --- a/mercurial/mail.py
    +++ b/mercurial/mail.py
    @@ -339,7 +339,7 @@ def _encode(ui, s, charsets) -> Any:
                     ui.warn(_(b'ignoring invalid sendcharset: %s\n') % ocs)
             else:
                 # Everything failed, ascii-armor what we've got and send it.
    -            return s.encode('ascii', 'backslashreplace')
    +            return s.encode('ascii', 'backslashreplace'), b'us-ascii'
         # We have a bytes of unknown encoding. We'll try and guess a valid
         # encoding, falling back to pretending we had ascii even though we
         # know that's wrong.
    

    Steps by steps, by replacing Any with real types, adjusting "wrong" types like in the first example and fixing bugs, we finally get the whole module (almost) completely annotated.


  • Meetup Cloud Native Computing Nantes - Juin 2019 - Linkdump

    2019/06/20 by Arthur Lutz

    Hier, je suis allé au Meetup Cloud Native Computing Nantes sur KubeCon et la sécurité avec Kubernetes.

    Gaëlle Acas et Eric Briand ont présenté un retour sur la KubeCon Europe 2019.

    https://www.logilab.org/file/10132592/raw/D9cHf74XkAI49HJ.jpg

    Alexandre Roman a présenté "La sécurité avec Kubernetes et les conteneurs Docker".

    https://www.logilab.org/file/10132593/raw/D9cNszLXsAAVqcX.jpg

    Beaucoup de technologies ont été mentionnées ou discutées. À défaut de faire un résumé de ce qui s'y est dit, voici quelque liens collecté pendant le meetup :

    Merci au Meetup Cloud Native Computing Nantes, au VMware User Group, à Dell pour le sponsoring.


  • Mercurial conference in Paris: May 28th, 2019

    2019/05/03 by Marla Da Silva

    Mercurial Paris conference will take place on May 28th at Mozilla's headquarters, in Paris.

    Mercurial is a free distributed Source Control Management system. It offers an intuitive interface to efficiently handle projects of any size. With its powerful extension system, Mercurial can easily adapt to any environment.

    This first edition targets organizations that are currently using Mercurial or considering switching from another Version Control System, such as Subversion.

    Attending the conference will allow users to share ideas and version control experiences in different industries and at a different scale. It is a great opportunity to connect with Mercurial core developers and get updates about modern workflow and features.

    You are welcome to register here and be part of this first edition with us!

    https://www.logilab.org/file/10131926/raw

    Mercurial conference is co-organized by Logilab, Octobus & Rhode-Code.


  • Les objectifs et l'histoire des présentations internes "5mintalk"

    2019/04/16 by Arthur Lutz

    Le partage de la connaissance est une composante importante à Logilab. Elle se décline en de nombreux formats dont je ne pourrais pas faire une liste exhaustive, parmi lesquels : la documentation interne, les communautés de logiciel libre, les listes de discussion, stackoverflow ou autres supports de ce type, l'organisation ou la participation à des conférences techniques et meetup en tant qu'auditeur ou en tant qu'orateur... et les "5mintalks".

    Les 5mintalk sont des présentations internes à Logilab, qui durent rarement 5 minutes et visent les objectifs suivants :

    • partager sa connaissance et diffuser les bonnes pratiques ;
    • faire connaître les atouts et les difficultés d'un projet aux autres salariés ;
    • faire des point d'étape sur des nouveautés liées aux services internes ;
    • fournir un moment d'attention partagé pour une entreprise distribuée sur deux sites géographiques (Paris et Toulouse) et de nombreuses personnes en télétravail (Nantes, Valence, Nice) ;
    • fournir un "espace protégé et bienveillant" pour que les personnes puissent s'exercer à la prise de parole en public, ce qui peut ensuite se transformer en prise de parole en public dans le cadre de conférences ;
    • s'entraîner à synthétiser et transmettre ses idées.

    Tout cela se fait sur la base du volontariat.

    Depuis 2018, nous utilisons de plus en plus la visioconférence pour faire ces présentations, afin que les personnes en télétravail et les sites géographiques distribués puissent les suivre.

    Depuis 2018 aussi, nous encourageons et nous formons à l'enregistrement de ces présentations sous forme de screencast pour que les absents puissent bénéficier de ces contenus en différé. Ces contenus sont ensuite partagés sur une instance peertube interne (peertube est un formidable logiciel de partage vidéo). Ces contenus peuvent aussi être utiles aux nouvelles recrues.

    https://www.logilab.org/file/10131502/raw/peertube.png

    Bien qu'on nous le demande parfois, ces contenus ne sont pas visibles de l'extérieur pour deux raisons principales. La première est l'aspect "espace protégé", qui permet l'expérimentation, alors qu'un certain niveau de qualité serait requis pour un publication externe. Avant de publier sur notre peertube interne, les personnes redemandent souvent pour vérifier que ce ne sera pas rendu public. La seconde raison est que nous faisons librement référence aux projets clients et à la manière dont ils sont réalisés, en incluant des détails qui ne sont pas partageables à l'extérieur.

    Les contenus sont très variés :

    • nos pratiques techniques ;
    • notre veille technologique ;
    • métiers de certains projets clients ;
    • retour suite à une conférence ;
    • activités en dehors du cadre professionnel.

    Vous pouvez retrouver la description succincte du contenu des présentations sur le mot-dièse #5mintalk sur notre instance mastodon, pour participer à ces échanges de pratiques... rejoignez nous.


  • Mercurial mini-sprint: from April 4th to 7th in Paris

    2019/03/19 by Marla Da Silva

    Logilab co-organizes with Octobus, a mini-sprint Mercurial to be held from Thursday 4 to Sunday 7 April in Paris.

    https://www.logilab.org/file/10131359/raw

    Logilab will host mercurial mini-sprint in its Paris premises on Thursday 4 and Friday 5 April. Octobus will be communicating very soon the place chosen to sprint during the weekend.

    To participate to mercurial mini-sprint, please complete the survey by informing your name and which days you will be joining us.

    Some of the developers working on mercurial or associated tooling plan to focus on improving the workflow and tool and documentation used for online collaboration through Mercurial (Kalithea, RhodeCode, Heptapod, Phabricator, sh.rt, etc. You can also fill the pad below to indicate the themes that you want to tackle during this sprint: https://mensuel.framapad.org/p/mini-sprint-hg

    Let's code together!


  • Retour sur le Workshop Prometheus et Grafana - Nantes 2019

    2019/03/08 by Arthur Lutz

    Hier soir j'ai participé à un workshop/meetup sur Prometheus et Grafana co-organisé par le Meetup Nantes Monitoring et le Meetup Cloud Native Computing Nantes.

    Le workshop était super bien préparé sous forme d'un dépôt git avec des instructions, des questions, des solutions : https://github.com/samber/workshop-prometheus-grafana Si ces technos vous intéressent, je vous encourage vivement à dérouler ce workshop.

    https://www.logilab.org/file/10131298/raw/Screenshot%20from%202019-03-08%2010-23-11.png

    J'ai parcouru la liste des exporters https://prometheus.io/docs/instrumenting/exporters/

    La liste des exporters qui pourraient nous intéresser à Logilab (technologies qu'on utilise) :

    On a aussi discuté avec des membres du workshop d'autres outils de métriques :

    Pour avoir des storage-schema.conf comme dans graphite, il faut avoir plusieurs prometheus qui se "scrape" les uns les autres avec des schémas de rétention et de granularité différents.

    Apparemment prometheus n'est pas facile à scaler, cortex est un projet qui essaye de le faire : https://www.cncf.io/blog/2018/12/18/cortex-a-multi-tenant-horizontally-scalable-prometheus-as-a-service/

    Bref, un excellent meetup mené avec brio par Samuel Berthe et Mickael Alibert. Merci à Epitech Nantes pour l'acceuil et à Zenika pour l'apéro à la fin du workshop.


  • Logilab trip report for FOSDEM 2019

    2019/02/13 by Nicolas Chauvat
    https://fosdem.org/2019/support/promote/wide.png

    A very large conference

    This year I attended the FOSDEM in Brussels for the first time. I have been doing free software for more than 20 years, but for some reason, I had never been to FOSDEM. I was pleasantly surprised to see that it was much larger than I thought and that it gathered thousands of people. This is by far the largest free software event I have been to. My congratulations to the organizers and volunteers, since this must be a huge effort to pull off.

    My presentation about CubicWeb

    I went to FOSDEM to present Logilab's latest project, a reboot of CubicWeb to turn it into a web extension to browse the web of data. The recording of the talk, the slides and the video of the demo are online, I hope you enjoy them and get in touch with me if you are to comment or contribute.

    My highlights

    As usual, the "hallway track" was the most useful for me and there are more sets of slides I read than talks I could attend.

    I met with Bram, the author of redbaron and we had a long discussion about programming in different languages.

    I also met with Octobus. We discussed Heptapod, a project to add Mercurial support to Gitlab. Logilab would back such a project with money if it were to become usable and (please) move towards federation (with ActivityPub?) and user queries (with GraphQL?). We also discussed the so-called oxydation of Mercurial, which consists in rewriting some parts in Rust. After a quick search I saw that tools like PyO3 can help writing Python extensions in Rust.

    Some of the talks that interested me included:

    • Memex, that reuses the name of the very first hypertext system described in the litterature, and tries to implement a decentralized annotation system for the web. It reminded me of Web hypothesis and W3C's annotations recommendation which they say they will be compatible with.
    • GraphQL was presented both in GraphQL with Python and Testing GraphQL with Javascript. I have been following GraphQL about two years because it compares to the RQL language of CubicWeb. We have been testing it at Logilab with cubicweb-graphql.
    • Web Components are one of the options to develop user interfaces in the browser. I had a look at the Future of Web Components, which I relate to the work we are doing with the CubicWeb browser (see above) and the work the Virtual Assembly has been doing to implement Transiscope.
    • Pyodide, the scientific python stack compiled to Web Assembly, I try to compare it to using Jupyter notebooks.
    • Chat-over-IMAP another try to rule them all chat protocols. It is right that everyone has more than one email address, that email addresses are more and more used as logins in many web sites and that using these email addresses as instant-messaging / chat addresses would be nice. We will see if it takes off!

  • Rencontres Debian Nantes - janvier 2019

    2019/01/30 by Arthur Lutz

    Le mardi 29 janvier 2019 entre 19h à 21h, des contributeurs et utilisateurs de Debian se sont rencontré pour échanger sur Debian. Debian est un système d'exploitation libre pour votre ordinateur. Un système d'exploitation est une suite de programmes de base et d’utilitaires permettant à un ordinateur de fonctionner.

    Merci à Capensis pour l’accueil dans ses locaux.

    Trois présentations ont été faites :

    https://social.logilab.org/system/media_attachments/files/000/083/740/original/fdb79bdc819cb6f6.png

    On a aussi parlé de l'association Debian France qui soutien nos rencontres. Rendez vous à la mini debconf Marseille ?


  • Logilab à Pas Sage en Seine 2018 #PSES2018

    2018/07/13 by Arthur Lutz

    Nous étions présents à la conférence Pas Sage en Seine 2018 pour assister aux conférences, mais aussi pour participer à la tenue du stand de l'APRIL dont Logilab est adhérente depuis sa création pour soutenir la promotion et la défense du logiciel libre.

    Voici un court retour sous forme de notes sur les conférences auxquelles nous avons assistées et qui sont en lien avec notre activité.

    Le programme était chargé, retrouvez le sur https://programme.passageenseine.fr/

    Conf zero knowledge webapp

    M4Dz de AlwaysData a effectué avec brio cette présentation.

    Article wikipedia sur Zero Knowledge Proof

    Dans le navigateur, certains acronymes sont familiers, d'autres un peu moins :

    • CORS
    • CSP
    • SRI - protection (signature de code)
    • Referrer-Policy
    • Key-storage (WebCrypto, File-API), éviter LocalStorage (peut être purgé comme du cache)

    WebAssembly (ASMjs) - prévient la lecture du code executé et rend l'extraction de données complexe. Plus difficile d'exploiter un binaire que un bout de JS où on peut se brancher où on veut (ralentir les attaques).

    Pendant les questions/réponses il a été question de "chiffrement homomorphique" comme potentielle solution pour les questions d'indexations de contenus chiffrés.

    Applications où y des choses similaires, dont certaines que nous utilisons à Logilab :

    Full-remote : guide de survie en environnement distant

    Encore une fois M4Dz de AlwaysData.

    Beaucoup de contenu, mais j'ai bien aimé les notions suivantes :

    • mentorat
    • mini-projet interne pour débuter - pour aller discuter avec les anciens
    • manifesto : exemple http://remoteonly.org (auquel on peut apporter quelques critiques)
    • exemple de remote le matin, pour ensuite être dans les bureaux l'après-midi
    • environnement sonore (à personnaliser)

    Pas mal de propos sur les canaux de communication:

    • tchat / voice / video / documents
    • exemple de github qui a enlevé le mail de ses outils de communication
    • virtualopenspace, notamment pour pause café (voir notre inspiration peopledoc et gitlab)
    • abuser des status type jabber/xmpp - pour communiquer sur notre disponibilité (notamment quand on a besoin d'être concentré et pas interrompu)

    Le temps de trajet peut être utile pour décompreser ou se mettre en condition pour travailler. Selon M4Dz, c'est reproductible en teletravail (aller faire un tour du quartier).

    Exemples de rencontres informelles entre télétravailleurs : nextcloud a une équipe très distribuée, ils vont travailler chez les uns les autres (ceux qui ont des affinités entre eux).

    À voir absolument si votre entreprise a une reflexion sur le télétravail, même en partiel (comme c'est le cas à Logilab).

    Jour 2

    Privacy by design

    Notes :

    • GRDP check list
    • déléger l'authentification à l'autres par exemple : openid
    • libjs : jwcrypto, jsencrypt, js-nacl (lien dans les slides pour la liste complète)
    • séparer les consentements (par service tiers)
    • exemple de nextcloud qui fait bien les choses https://nextcloud.com/privacy/
    • matomo (ex-piwik) fait bien les choses en terme de respect de vie privée
    • documentation des api (swagger et apiary pour supprimer les données

    Sur la pseudonimiation (pour publier des jeux de données), M4Dz nous a parlé de Differential privacy

    Crypto quantique

    Comment commencer à tester la crypto quantique en pratique :

    Conclusion, il est urgent d'attendre, on a plein d'autres problèmes de securité à résoudre.

    GRPDBookClub

    Super retour d'experience sur comment aborder un texte de loi ou une reglementation compliquée de manière collective.

    La RGPD pour les noobs

    Excellent complément de la conférence précédente sur le RGPD.

    Fin

    Voilà. Plein d'autres conférences méritent d'être visionnées sur https://video.passageenseine.fr/ (peertube, what else?), bravo pour la captation, la diffusion en direct et la mise à disposition des contenus.

    Bravo à tout l'équipe d'organisation pour les contenus riches et variés de cette édition du festival. Et merci à toutes les personnes avec qui j'ai pu échanger en marge des conférences

    Si vous êtes arrivés jusqu'ici, déjà bravo, et puis sachez que Logilab recrute, rejoignez nous pour travailler sur ces questions.

    Logilab recrute!


  • Experiment to safely refactor your code in Python

    2018/05/05 by Nicolas Chauvat

    "Will my refactoring break my code ?" is the question the developer asks himself because he is not sure the tests cover all the cases. He should wonder, because tests that cover all the cases would be costly to write, run and maintain. Hence, most of the time, small decisions are made day after day to test this and not that. After some time, you could consider that in a sense, the implementation has become the specification and the rest of the code expects it not to change.

    Enters Scientist, by GitHub, that inspired a Python port named Laboratory.

    Let us assume you want to add a cache to a function that reads data from a database. The function would be named read_from_db, it would take an int as parameter item_id and return a dict with attributes of the items and their values.

    You could experiment with the new version of this function like so:

    import laboratory
    
    def read_from_db_with_cache(item_id):
        data = {}
        # some implementation with a cache
        return data
    
    @laboratory.Experiment.decorator(candidate=read_from_db_with_cache)
    def read_from_db(item_id):
         data = {}
         #  fetch data from db
         return data
    

    When you run the above code, calling read_from_db returns its result as usual, but thanks to laboratory, a call to read_from_db_with_cache is made and its execution time and result are compared with the first one. These measurements are logged to a file or sent to your metrics solution for you to compare and study.

    In other words, things continue to work as usual as you keep the original function, but at the same time you experiment with its candidate replacement to make sure switching will not break or slow things down.

    I like the idea ! Thank you for Scientist and Laboratory that are both available under the MIT license.

    https://www.logilab.org/file/10128331/raw/chemistry.png

show 316 results